【问题标题】:How do I create a default dictionary of dictionaries如何创建字典的默认字典
【发布时间】:2016-08-26 18:39:20
【问题描述】:

我正在尝试编写一些涉及创建默认词典的代码。但是,我不知道如何初始化/创建这样的东西。我目前的尝试看起来像这样:

from collections import defaultdict
inner_dict = {}
dict_of_dicts = defaultdict(inner_dict(int))

这个默认字典的使用是为我从打开的文件中生成的每对单词(例如 [['M UH M', 'm oo m']] )设置由空格分隔的第一个单词作为外部字典中的键,然后为由空格分隔的第二个单词中的每个片段计算该片段的频率。

例如

[['M UH M', 'm oo m']] 
(<class 'dict'>, {'M': {'m': 2}, 'UH': {'oo': 1}})

现在刚刚运行它似乎没有输出任何错误,但是我只是想知道这样的事情是否真的会产生一个默认的字典字典。

抱歉,如果这是重复的,但是以前对这些问题的回答令人困惑并且在不同的背景下。

【问题讨论】:

  • 好吧,您当前粘贴的代码无效...inner_dict 被定义为字典,然后您尝试将其称为inner_dict(int) ...

标签: string python-3.x dictionary nested defaultdict


【解决方案1】:

其他答案提出了替代解决方案或表明您可以使用 d = defaultdict(dict) 制作默认字典字典

但问题是如何制作默认词典的默认词典,我的第一次尝试是这样的:

from collections import defaultdict
my_dict = defaultdict(defaultdict(list))

但是这会引发错误:*** TypeError: first argument must be callable or None

所以我的第二次尝试是使用 lambda 关键字创建一个可调用的匿名函数:

from collections import defaultdict
my_dict = defaultdict(lambda: defaultdict(list))

这比使用常规函数的替代方法更简洁:

from collections import defaultdict
def default_dict_maker():
    return defaultdict(list)
my_dict = defaultdict(default_dict_maker)

您可以通过分配来检查它是否有效:

my_dict[2][3] = 5
my_dict[2][3]
>>> 5

或者通过尝试返回一个值:

my_dict[0][0]
>>> []
my_dict[5]
>>> defaultdict(<class 'list'>, {})

tl;博士

这是你的在线答案my_dict = defaultdict(lambda: defaultdict(list))

【讨论】:

    【解决方案2】:

    要初始化创建字典的defaultdict 作为默认值,您可以使用:

    d = defaultdict(dict)
    

    对于这个特殊问题,collections.Counter 会更合适

    >>> from collections import defaultdict, Counter
    >>> d = defaultdict(Counter)
    >>> for a, b in zip(*[x.split() for x in ['M UH M', 'm oo m']]):
    ...    d[a][b] += 1
    >>> print(d)
    defaultdict(collections.Counter,
                {'M': Counter({'m': 2}), 'UH': Counter({'oo': 1})})
    

    编辑

    您表示有兴趣对没有Counter 的等效项发表评论。这是使用普通 dict 的等价物

    >>> from collections import defaultdict
    >>> d = defaultdict(dict)
    >>> for a, b in zip(*[x.split() for x in ['M UH M', 'm oo m']]):
    ...    d[a][b] = d[a].get(b, 0) + 1
    >>> print(d)
    defaultdict(dict, {'M': {'m': 2}, 'UH': {'oo': 1}})
    

    【讨论】:

    • 这是一种优雅的方式!没有Counter,有什么办法可以做到这一点,而只是默认字典和字典?
    • @IndifferentPotato 我使用defaultdict(dict)添加了等效项
    • 只有普通 dict 的等价物输出一个 AttributeError: 'list' object has no attribute 'split''。 ://
    • @IndifferentPotato 仅当您输入的代码不是答案中的内容时。检查您输入的内容。
    【解决方案3】:

    您也可以使用普通字典及其setdefault 方法。

    my_dict.setdefault(key, default) 将查找 my_dict[key] 和 ...

    • ...如果键已经存在,则返回其当前值而不修改它,或者...
    • ...分配默认值 (my_dict[key] = default),然后返回。

    因此,当您想从外部字典而不是普通的 my_dict[key] 获取值时,您可以始终调用 my_dict.setdefault(key, {}) 来检索分配给此键的实际值(如果它存在),或者获取新的空字典作为默认值,它也会自动存储到您的外部字典中。

    例子:

    outer_dict = {"M": {"m": 2}}
    
    inner_dict = d.setdefault("UH", {})
    # outer_dict = {"M": {"m": 2}, "UH": {}}
    # inner_dict = {}
    inner_dict["oo"] = 1
    # outer_dict = {"M": {"m": 2}, "UH": {"oo": 1}}
    # inner_dict = {"oo": 1}
    
    inner_dict = d.setdefault("UH", {})
    # outer_dict = {"M": {"m": 2}, "UH": {"oo": 1}}
    # inner_dict = {"oo": 1}
    inner_dict["xy"] = 3
    # outer_dict = {"M": {"m": 2}, "UH": {"oo": 1, "xy": 3}}
    # inner_dict = {"oo": 1, "xy": 3}
    

    这样你总是得到一个有效的inner_dict,要么是一个空的默认值,要么是给定键已经存在的那个。由于字典是可变数据类型,修改返回的inner_dict也会修改outer_dict里面的字典。

    【讨论】:

      猜你喜欢
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 1970-01-01
      • 2022-12-09
      相关资源
      最近更新 更多