2016-05-02 13 views
0

aktualisiert Wenn gab mir einen Fehlerdas verschachtelte Wörterbuch unter defaultdict

sagt

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "program.py", line 18, in train_ngrams 
    if graphemes[i] not in mydict[phonemes[i]].keys(): 
AttributeError: 'str' object has no attribute 'keys' 

Mein Code versuchen, meinen Wörterbuch unter einem verschachtelten collection.defaultdict Python zu aktualisieren:

import csv 
from collections import defaultdict 

def train_ngrams(train_file): 
    mydict = defaultdict(dict) 
    phonemes = [] 
    graphemes = [] 
    with open(train_file, 'r') as f: 
     reader = csv.reader(f) 
     next(reader) 
     for p, g in reader: 
      phonemes += p.split() 
      graphemes += g.split() 
      for i in range(len(phonemes)): 
       if phonemes[i] not in mydict.keys(): 
        mydict.update({phonemes[i] : graphemes[i]}) 
        if graphemes[i] not in mydict[phonemes[i]].keys(): 
         mydict[phonemes[i]].update({phonemes[i] : (graphemes.count(graphemes[i]) for graphemes[i] in graphemes) - 1}) 
        else: 
         mydict[phonemes[i]][graphemes[i]] += 1   

Nun, was ich ist Ich versuche, das Wörterbuch zu aktualisieren, während ich durch eine CSV-Datei iteriere. Und hier möchte ich zuerst prüfen ob es in der defaultdict schon ist. Wenn nicht, möchte ich ein Schlüssel-Wert-Paar erstellen.

Und der Wert hier in der defaultdict wird später tatsächlich verwendet, um ein verschachteltes normales Wörterbuch zu implementieren, das einige Frequenzstümpfe speichert. Hier

ein Beispiel:

defaultdict(<class 'dict'>, {'T': {'t': 2}, 'UH': {'oo': 1}}) 

Was ist eine prägnante Art und Weise, diesen Fehler zu umgehen? Beachten Sie, dass in diesem Teil defaultdict erforderlich ist.

EDIT:

train_ngrams("training-data-ex1.csv") 

Der gewünschte Ausgang

defaultdict(<class 'dict'>, {'T': {'t': 2}, 'UH': {'oo': 1}}) 

EDIT sein sollte:

Die Probe txt-Datei

phonemes,graphemes 
T UH T,t oo t 
+0

'mydict [phonemes [i]]' gibt einen Schlüsselwert zurück – styvane

+0

Was möchten Sie tun? Mit den Zeilen "mydict.update ({phonemes [i]: graphemes [i]}); wenn Grapheme [i] nicht in mydict [phonemes [i]]. keys(): 'Sie überprüfen grundsätzlich' wenn Grapheme [i] nicht in Grapheme [i] .keys(): ', was scheint nicht zu machen viel Sinn. –

+0

@tobias_k Ich möchte überprüfen, ob das Schlüssel- und Wertepaar im Standarddict vorhanden ist, wenn nicht, müsste ich es mit diesem Wert aktualisieren und paaren, so dass ich es tatsächlich manipulieren und die richtige Ausgabe erhalten kann, die ich wollte. –

Antwort

1

Wenn Sie Elemente wollen paaren, Sie müssenverwenden, kein Double-for-Loop.

mydict = collections.defaultdict(lambda: collections.defaultdict(int)) 
with open("training-data-ex1.csv") as f: 
    reader = csv.reader(f) 
    next(reader) # skip header 
    for phonemes, graphemes in reader: 
     for p, g in zip(phonemes.split(), graphemes.split()): 
      mydict[p][g] += 1 

Dies verwendet eine defaultdict von defaultdict von int, so sieht das Ergebnis ein bisschen komisch, aber es ist im Grunde nur, was man wollte: defaultdict(<function <lambda> at 0x7fd297740840>, {'T': defaultdict(<class 'int'>, {'t': 2}), 'UH': defaultdict(<class 'int'>, {'oo': 1})}), oder, ohne dass alle defaultdict vorformulierten, {'T': {'t': 2}, 'UH': {'oo': 1}}.

+0

Würde zip zuerst die Duplikate in einem Container löschen und dann konvertieren es zu einem Diktat? –

+0

Nein, 'zip' wiederholt nur die Paare. Anstatt duples zu löschen und dann count zu verwenden, wiederhole einfach die Paare und zähle +1 für jeden. Viel einfacher. –

+0

Ich sehe, ich werde das definitiv versuchen und sehen, wie es geht. Vielen Dank! –