2017-03-03 2 views
0

Ich versuche, alle Wörter und sein Tag und zählen in ein Wörterbuch zu zählen. Allerdings bekomme ich immer einen KeyError und ich verstehe nicht warum.Key Fehler Python

sent = [[('Merger', 'NOUN'), ('proposed', 'VERB')], [('Wards', 'NOUN'), ('protected', 'VERB')]] 

dicts = {} 

for x in sent: 
    for y in x: 
     if y[0] in dicts.keys(): 
      dicts[y[0]][y[1]] = 1 
     else: 
      dicts[y[0]][y[1]] += 1 

Fehler:

KeyError    Traceback (most recent call last) 
    <ipython-input-19-17c6695bd911> in <module>() 
    17    dicts[y[0]][y[1]] = 1 
    18   else: 
---> 19    dicts[y[0]][y[1]] += 1 

    KeyError: 'Merger' 
+0

Sie haben zwei schnelle Antworten von High-rep Leute, aber ich bin zu kämpfen, die Nützlichkeit von 'dicts [y [0] zu verstehen ] [y [1]] + = 1'. Welche Ausgabe erwarten Sie? – roganjosh

+0

@roganjosh Hallo, ich versuche ein verschachteltes Wörterbuch zu erstellen. So wäre es {Merge: {Nomen: 1}} –

+0

Ich denke, es wurde tatsächlich mit TerryA's bearbeiteter Antwort angesprochen. Es sah einfach nicht gut aus, ich fragte mich, ob etwas Umständliches vor sich ging. – roganjosh

Antwort

1

Sie haben Ihre conditionals falsch herum bekam. Sie möchten zuerst überprüfen, ob der Schlüssel im Wörterbuch vorhanden ist. Ist dies nicht der Fall, erstellen Sie den Schlüssel. Dann haben Sie zu weit geschachtelt. Sie brauchen nur dicts[y[0]]

Es gibt eine einfache Lösung: add not vor in dicts.keys(), aber dann von [y[1]] loszuwerden.

In voller Länge:

for x in sent: 
    for y in x: 
     if y[0] not in dicts.keys(): 
      dicts[y[0]] = 1 
     else: 
      dicts[y[0]] += 1 
2

Sie sollten auch bei collections.defaultdict und collections.Counter suchen betrachten:

A defaultdict wird automatisch in einem Standardwert füllen, ein Counter ein dict zum Zählen speziell ist:

from collections import defaultdict 
from collections import Counter 

sent = [[('Merger', 'NOUN'), ('proposed', 'VERB')], [('Wards', 'NOUN'), ('protected', 'VERB')]] 

dicts = defaultdict(Counter) # A default dictionary of Counters 
for x in sent: 
    for y in x: 
     dicts[y[0]][y[1]] += 1 

print(dicts) 
# defaultdict(<class 'collections.Counter'>, {'Merger': Counter({'NOUN': 1}), 'proposed': Counter({'VERB': 1}), 'Wards': Counter({'NOUN': 1}), 'protected': Counter({'VERB': 1})}) 

Wenn Sie die Counter überspringen möchten Sie können nur eine Hilfsfunktion verwenden, die eine defaultdict(int) zurückgibt und keine Argumente:

from collections import defaultdict 

def int_dict(): 
    return defaultdict(int) 

dicts = defaultdict(int_dict) 
for x in sent: 
    for y in x: 
     dicts[y[0]][y[1]] += 1 

print(dicts) 
# defaultdict(<function a at 0x112c48048>, {'Merger': defaultdict(<class 'int'>, {'NOUN': 1}), 'proposed': defaultdict(<class 'int'>, {'VERB': 1}), 'Wards': defaultdict(<class 'int'>, {'NOUN': 1}), 'protected': defaultdict(<class 'int'>, {'VERB': 1})}) 
+0

So ziemlich, was ich gerade posten wollte, also werde ich nicht duplizieren. Sie könnten den hässlichen Indexzugriff auf das Tupel vermeiden, indem Sie es im 'for in' entpacken. z.B. 'für Name, typ in x:' –