将集合的 defaultdict 替换为带有 setdefault 的普通字典

Replace collections' defaultdict by a normal dict with setdefault

我经常使用 collections.defaultdict 来将一个元素附加到 d[key] 而无需先将其初始化为 [] (好处:你不需要这样做:if key not in d: d[key] = []):

import collections, random
d = collections.defaultdict(list)  
for i in range(100):
    j = random.randint(0,20)
    d[j].append(i)  # if d[j] does not exist yet, initialize it to [], so we can use append directly

现在我意识到我们可以简单地使用普通的 dictsetdefault:

import random
d = {}
for i in range(100):
    j = random.randint(0,20)
    d.setdefault(j, []).append(i)

问题:当使用值为列表的 dict 时,是否有充分的理由使用 collections.defaultdict 而不是第二种方法(使用简单的 dictsetdefault), 或者它们完全等价?

collections.defaultdict 通常性能更高,它针对此任务进行了优化并由 C 语言实现。但是,如果要访问生成的字典中不存在的键以生成 KeyError 而不是插入空列表,则应使用 dict.setdefault。这是最重要的实际区别。

除了 Chris_Rands 的回答之外,我想进一步强调使用 defaultdict 的一个主要原因是如果您希望密钥访问始终成功,并且在以下情况下插入默认值有 none。 这可以出于任何原因,一个完全有效的原因是能够使用 [] 而不是每次访问之前都必须调用 dict.setdefault 的便利。

另请注意,如果以前从未访问过该密钥,key in default_dict 仍将 return False,因此您仍然可以检查 defaultdict 中是否存在密钥如有必要。这允许在不检查列表是否存在的情况下附加到列表,但也可以在必要时检查列表是否存在。

使用 defaultdict 时,您可以进行就地添加:

import collections, random
d = collections.defaultdict(list)  
for i in range(100):
    j = random.randint(0,20)
    d[j] += [i]

没有像d.setdefault(j, []) += [i]这样的等效结构,它给出SyntaxError: cannot assign to function call