Добавление ключей к defaultdict (dict)

У меня есть defaultdict, который выглядит так:

my_dict = defaultdict(dict)

который будет распечатываться:

defaultdict(<class 'dict'>, {})

У меня также есть два списка, которые выглядят следующим образом:

list1 =  ["W", "IY", "W"]
list2 =  ["w", "ee", "w"]

Я хотел бы создать файл по умолчанию, который выглядит так:

defaultdict(<class 'dict'>, {'W': {'w': 2}, 'IY': {'ee': 1}}

который имеет список1 в словаре как ключи, с ключами в качестве следующего списка с отдельным словарем, считая экземпляры списка2 как значения.

Пока у меня есть это:

from collections import defaultdict

d = defaultdict(dict)

list1 = ["W", "IY", "W"]
list2 = ["w", "ee", "w"]

for char in list1:
    d[char] += 1

Я знаю, что это неверно, так как defaultdict (dict) нельзя трактовать таким образом. Могу ли я сделать это? Любая помощь будет принята с благодарностью:)

Ответ 1

EDITED на основе комментария к моему первоначальному ответу.

Вам понадобится сопоставление всех возможных фонем ко всем возможным написаниям (графемы).

phonemes = {TH : [th], O : [o], OH : [oh, oo]}

for char in set(list1):
    if char not in d:
        d[char] = {char.lower() : {phone : list2.count(phone) for phone in phonemes[char]}}

Ответ 2

Вот решение, использующее collections.Counter.

import collections
d = collections.defaultdict(collections.Counter)

list1 = ["O", "TH", "O", "O"]
list2 = ["o", "th", "o", "o1"]

for key, value in zip(list1, list2):
    d[key].update([value])

>>> d
defaultdict(<class 'collections.Counter'>, {'TH': Counter({'th': 1}), 'O': Counter({'o': 2, 'o1': 1})})
>>>

Пока это строго не соответствует вашим требованиям, collections.Counter наследует от dict, поэтому он имеет все атрибуты dict

Ответ 3

Вы также можете использовать вложенный defaultdict и zip так:

d = defaultdict(lambda: defaultdict(int))
for k, v in zip(list1, list2):
    d[k][v] += 1
# d['TH']['th']: 1
# d['O']['o']: 2

или, если вы хотите сохранить свою структуру данных:

d = defaultdict(dict)
for k, v in zip(list1, list2):
    d[k][v] = d[k].get(v, 0) + 1  
    # use dict.get(key, default=None) and specify an appropriate default value (0)

Используя dict.get(key, default=None), вы можете получить доступ к ключевым значениям общего dict, как и файл defaultdict, однако обновление является немного более неуклюже.

Ответ 4

Немного разные решения:

import collections

phonemes  = ["W", "IY", "O", "W", "O"]
graphemes = ["w", "ee", "o", "w", "oh"]

# count all the (phoneme, grapheme) pairs
counter = collections.Counter(zip(phonemes, graphemes))

# convert to desired data structure
d = collections.defaultdict(dict)
for (phoneme, grapheme), count in counter.items():
    d[phoneme][grapheme] = count

print(d)

печатает:

defaultdict(<class 'dict'>, {'W': {'w': 2}, 'O': {'oh': 1, 'o': 1}, 'IY': {'ee': 1}})