2016-05-22 18 views
0

Ich versuche, Zähler in einer Liste von Wörterbüchern zu verwenden, um zu zählen, wie oft jedes Wörterbuch sich wiederholt.Zähler für eine Liste von Python-Wörterbüchern verwenden

Nicht alle Wörterbücher in der Liste haben notwendigerweise die gleichen Schlüssel.

vermuten läßt Ich habe die folgende Liste:

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"}) 

Meine gewünschte Lösung ist

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

ich versucht habe

import collections 
c=collections.Counter(my_list) 

aber ich bekomme die folgenden Fehler

TypeError: unhashable type: 'dict' 

Haben Sie Vorschläge

Dank

+1

'{d [ "id"]: d für d in my_list}' –

+0

https: // wiki .python.org/moin/DictionaryKeys – dm295

+0

Sie können ein Wörterbuch nicht als Schlüssel in einem anderen Wörterbuch verwenden. –

Antwort

2

You can't use dictionary as a key in other dictionary. Deshalb erhalten Sie eine TypeError: unhashable type: 'dict'.

Sie können das Wörterbuch in eine JSON Zeichenfolge serialisieren, die als Wörterbuchschlüssel verwendet werden kann.

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

Warum kann ich das Wörterbuch nicht als Schlüssel in einem anderen Wörterbuch verwenden? Was kann ich tun, wenn in jedem Element keine eindeutigen Werte vorhanden sind? Das bedeutet, ich kann mich nicht darauf verlassen, dass sich die ID nicht wiederholt. –

+0

Sie können keinen austauschbaren Wörterbuchschlüssel verwenden. Dann kann sich sein Hash-Wert ändern und die Wörterbuchzuordnung wird falsch. –

0

Counter ist Werkzeug, das Elemente in einem iterable als dict speichert, wobei die Elemente repräsentieren dict.keys() und dict.values() repräsentieren die Anzahl der dieses Element in der iterable.

In einem Wörterbuch können Sie jedoch keine sich wiederholenden Schlüssel haben, da die Schlüssel eindeutig sein müssen. Es macht daher keinen Sinn, etwas zu zählen, da wir bereits wissen, dass es 1 ist. Andererseits können sich im Diktat repetitive Werte befinden. Zum Beispiel:

>>> 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}) 

Lassen Sie uns jetzt sagen, dass wir Liste der Wörterbücher haben, und wir wollen die Werte in diesen Wörterbücher begegnen; wie es der Fall in Ihrer Frage:

>>> 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}) 

Jetzt können Sie natürlich dieses Tupel nehmen und wandeln sie in einem dict:

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

oder sogar noch weiter gehen, und verwenden Sie named tuples von collections.namedtuple und identifizieren Sie Ihre Tupel nach Namen, auf die Sie später viel leichter und klarer Bezug nehmen können.

Hoffe, das hilft.

Erfahren Sie mehr über collections.Counter von der documentations oder diese nützliche set of examples. Sie können sich auch auf Videos von Raymond Hettinger (Python-Betreuer von collections toolbox) auf YouTube beziehen. Er hat einige tolle Tutorials zu verschiedenen Tools.

0

Leider dict sind nicht hashable. Also schreibe ich diesen Code. Das Ergebnis ist nicht wie Ihre gewünschte Lösung (weil nicht möglich), aber möglicherweise können Sie das verwenden.

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) 

dieser Code Rückkehr

[ 
    [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: sorry mein schlechtes Englisch

Verwandte Themen