简体   繁体   English

将键添加到defaultdict(dict)

[英]Adding keys to defaultdict(dict)

I have a defaultdict that looks like this: 我有一个看起来像这样的defaultdict:

my_dict = defaultdict(dict)

which will print out: 将打印出来:

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

I also have two lists, which look like this: 我还有两个列表,如下所示:

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

I would like to create a default dict which looks like this: 我想创建一个默认的dict,如下所示:

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

which has list1 within a dictionary as keys, with the keys as the next list with a separate dictionary, counting the instances of list2 as values. 其中list1在字典中作为键,键作为下一个列表,带有单独的字典,将list2的实例计为值。

So far I have this: 到目前为止我有这个:

from collections import defaultdict

d = defaultdict(dict)

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

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

I know that this is not correct, as the defaultdict(dict) cannot be treated this way. 我知道这是不正确的,因为defaultdict(dict)不能以这种方式处理。 Is there a way a I could do this? 我有办法做到这一点吗? Any help would be greatly appreciated :) 任何帮助将不胜感激 :)

Here is a solution using collections.Counter . 这是使用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})})
>>>

While this doesn't strictly follow your requirements, collections.Counter inherits from dict so it has all of dict 's attributes 虽然这并不严格遵循您的要求,但collections.Counter继承自dict因此它具有dict的所有属性

EDITED based on the comment on my original answer. 根据我原来答案的评论编辑。

You'll need a mapping of all possible phonemes to all possible spellings (graphemes). 您需要将所有可能的音素映射到所有可能的拼写(字形)。

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

You can also use a nested defaultdict and zip like so: 你也可以像这样使用嵌套的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

or, if you want to keep your data structure: 或者,如果您想保留您的数据结构:

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)

Using dict.get(key, default=None) allows you to access key-values of a common dict much like those a defaultdict, however, updating is a little more clunky. 使用dict.get(key, default=None)允许您访问常见dict键值,就像那些dict.get(key, default=None) dict一样,但是,更新更加笨拙。

Slightly different take on a solution: 采取一种解决方案略有不同:

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)

prints: 打印:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM