2016-05-02 4 views
0

При попытке обновить мой словарь под вложенной collection.defaultdict Python дал мне ошибкуОбновление вложенного словаря под defaultdict

Сказать

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' 

Мой код:

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   

Ну вещь я Я пытаюсь обновить словарь, когда я перебираю файл csv. И здесь я сначала хочу проверить, находится ли он в defaultdict. Если нет, то я хочу создать пару ключей и значений.

И значение здесь, в defaultdict, фактически будет использовано позже для реализации вложенного нормального словаря, в котором хранятся некоторые данные о частоте.

Вот пример:

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

Что такое краткий способ справиться с этой ошибкой? Обратите внимание, что в этой части требуется defaultdict.

EDIT:

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

Нужный выход должен быть

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

EDIT:

Образец TXT файл

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

'mydict [phonemes [i]]' возвращает значение ключа – styvane

+0

Что вы пытаетесь сделать? С строками 'mydict.update ({фонемы [i]: graphemes [i]}); если graphemes [i] не в mydict [phonemes [i]]. keys(): 'вы в основном проверяете', если graphemes [i] не в graphemes [i] .keys(): ', который, похоже, не делает много смысла. –

+0

@tobias_k Я хочу проверить, существует ли эта пара ключей и значений в defaultdict, если нет, тогда мне придется обновить ее с этим значением и парой, чтобы я мог фактически манипулировать ею и получить правильный результат, который я хотел. Добавлен –

ответ

1

Если вы хотите паре элементов, вы должны использовать zip, а не двойного цикла.

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 

Это использует defaultdict из defaultdict из int, поэтому результат выглядит немного странно, но это в основном только то, что вы хотели: defaultdict(<function <lambda> at 0x7fd297740840>, {'T': defaultdict(<class 'int'>, {'t': 2}), 'UH': defaultdict(<class 'int'>, {'oo': 1})}), или, не все, что defaultdict шаблонный, {'T': {'t': 2}, 'UH': {'oo': 1}}.

+0

Будет ли zip сначала удалять дубликаты в контейнере, а затем конвертировать это к диктору? –

+0

Нет, 'zip' просто повторяет пары. Вместо того, чтобы удалять обманы, а затем использовать count, просто перебирайте пары и подсчитывайте +1 для каждого. Гораздо проще. –

+0

Я вижу, я обязательно попробую это и посмотрю, как это происходит. Спасибо! –

Смежные вопросы