2016-05-22 4 views
0

各ディクショナリが何回繰り返しているかを調べるために、辞書のリストにcounterを使用しようとしています。Pythonディクショナリのリストでカウンタを使用する

リストのすべての辞書が必ずしも同じキーを持っているわけではありません。

私は次のリストを持っていると仮定することができます:

my_list=({"id":1,"first_name":"Jhon","last_name":"Smith"},{"id":2,"first_name":"Jeff","last_name":"Levi"},{"id":3,"first_name":"Jhon"},{"id":1,"first_name":"Jhon","last_name":"Smith"}) 

私の希望ソリューションは、私が

import collections 
c=collections.Counter(my_list) 

を試してみましたが、私は次のエラー

TypeError: unhashable type: 'dict' 
を取得

solution={ 
{"id":1,"first_name":"Jhon","last_name":"Smith"}:2 
{"id":2,"first_name":"Jeff","last_name":"Levi"}:1 
{"id":3,"first_name":"Jhon"}} 

です

あなたはどんな提案に

おかげ

+1

'{D [ "ID"]:my_listというにおけるDに対するD}' –

+0

のhttps://ウィキ.python.org/moin/DictionaryKeys – dm295

+0

辞書を別の辞書のキーとして使用することはできません。 –

答えて

2

You can't use dictionary as a key in other dictionaryを持っていますか。だからあなたはTypeError: unhashable type: 'dict'を取得します。

辞書をJSON文字列にシリアル化することができます。これは辞書キーとして使用できます。

import json 
import collections 

my_list = [{"id":1,"first_name":"Jhon","last_name":"Smith"}, 
      {"id":2,"first_name":"Jeff","last_name":"Levi"}, 
      {"id":3,"first_name":"Jhon"}, 
      {"id":1,"first_name":"Jhon","last_name":"Smith"}] 

c = collections.Counter(json.dumps(l) for l in my_list) 
print c 
>>> Counter({'{"first_name": "Jhon", "last_name": "Smith", "id": 1}': 2, 
      '{"first_name": "Jeff", "last_name": "Levi", "id": 2}': 1, 
      '{"first_name": "Jhon", "id": 3}': 1}) 
+0

辞書を他の辞書のキーとして使用できないのはなぜですか? さらに、各エレメントに固有の値がない場合はどうすればよいですか。つまり、IDはそれ自体を繰り返さないという事実には気づくことができません。 –

+0

変更可能な辞書キーは使用できません。そのハッシュ値が変更され、辞書のマッピングが正しく行われなくなります。 –

0

カウンタdict.keys()アイテムを表し、dict.values()が反復可能で、その項目のカウントを表す辞書として反復可能でアイテムを格納するツールです。

しかし、辞書では、キーは一意でなければならないため、繰り返しキーは使用できません。したがって、何かを数えることには意味がありません。私たちはすでにそれが1であることを知っているからです。一方、dictには繰り返し値が格納されていることがあります。たとえば、

>>> from collections import Counter 

>>> my_dict = {'a': 'me', 'b':'you', 'c':'me', 'd':'me'} 

>>> Counter(my_dict) # As plain dict. 
Counter({'b': 'you', 'a': 'me', 'c': 'me', 'd': 'me'}) 

>>> Counter(my_dict.values()) # As dict values. 
Counter({'me': 3, 'you': 1}) 

ここで、辞書のリストがあり、その辞書の値に対抗したいとします。あなたの質問の場合のように:

>>> my_dict = [ 
... {'age': 30, 'name': 'John'}, 
... {'age': 20, 'name': 'Jeff'}, 
... {'age': 30, 'name': 'John'}, 
... {'age': 25, 'name': 'John'} 
... ] 

>>> Counter(tuple(i.values()) for i in a) # As a generator of values as tuple. 
Counter({(30, 'John'): 2, (25, 'John'): 1, (20, 'Jeff'): 1}) 

今、あなたはもちろん、このタプルを取り、dictに変換することができます

>>> {key: value for key, value in b.items()} 
{(25, 'John'): 1, (30, 'John'): 2, (20, 'Jeff'): 1} 

またはさらに進んで、collections.namedtupleからnamed tuplesを使用して、あなたのを確認タプル名は後ほど簡単に参照できます。

これが役に立ちます。

collections.Counterについて詳しくは、documentationsまたはこの便利なset of examplesをご覧ください。また、YouTubeのRaymond Hettinger(Pythonのメンテナーcollectionsツールボックス)の動画を参照することもできます。彼はさまざまなツールに関する素晴らしいチュートリアルを用意しています。

0

残念ながら、dictはハッシュ可能ではありません。だから私はこのコードを書く。結果はあなたの希望する解決策と似ていません(可能ではないため)が、それを使用できるかもしれません。

ids_l = [i['id'] for i in my_list] 
ids_s = list(set(ids_l)) 

#k is basickly [id, how many] 
k = [[i,ids_l.count(i)] for i in ids_s] 

#finding my_list from id 
def finder(x): 
    for i in my_list: 
     if i['id'] == x: 
      return i 
res = [] 
for i in range(len(ids_s)): 
    #k[i][1] how many value 
    #finder(k[i][0]) return dict 
    res.append([k[i][1],finder(k[i][0])]) 
print(res) 

このコードリターン

[ 
    [2, {'id': 1, 'first_name': 'Jhon', 'last_name': 'Smith'}], 
    [1, {'id': 2, 'first_name': 'Jeff', 'last_name': 'Levi'}], 
    [1, {'id': 3, 'first_name': 'Jhon'}] 
] 

PS:申し訳ありませんが私の乏しい英語

関連する問題