defaultdict(lambda:None) 和 defaultdict(int) 的区别

6

当与defaultdict一起使用时,“TYPE lambda”到底是做什么的?我有一个例子,在这个例子中,即使将intlistlambda作为参数传递进去也可以正常工作:

d = defaultdict(int)
d['one'] = lambda x:x*x
d['one'](2)
4

d = defaultdict(list)
d['one'] = lambda x:x*x
d['one'](2)
4

d = defaultdict(lambda: None)
d['one'] = lambda x:x*x
d['one'](2)
4

每次我都得到相同的结果。那么使用lambda "default (lambda: None)"进行初始化的主要原因是什么?看起来defaultdict字典并不在乎传入的参数类型是什么。

您可以在以下链接中获取答案 https://dev59.com/mmoy5IYBdhLWcg3wo_gn#49184504 - Prashant Pathak
2个回答

7

只有在访问未明确添加到字典中的键时,您的示例才有意义:

>>> d = defaultdict(int)
>>> d['one']
0
>>> d = defaultdict(list)
>>> d['one']
[]
>>> d = defaultdict(lambda: None)
>>> d['one'] is None
True

如您所见,使用默认字典将为您尝试访问的每个键提供一个默认值。该默认值是通过调用您传递给构造函数的函数来获取的。因此,传递int将设置int()作为默认值(即0);传递list将设置list()作为默认值(即空列表[]);传递lambda: None将设置(lambda: None)()作为默认值(即None)。

这就是默认字典的作用。没有其他作用。

这样做的想法是,您可以设置默认值,而无需在首次访问键时手动设置它们。例如:

d = {}
for item in some_source_for_items:
    if item['key'] not in d:
        d[item['key']] = []

    d[item['key']].append(item)

当访问每个字典项时,仅设置一个新的空列表,可以简化为以下内容:

d = defaultdict(list)
for item in some_source_for_items:
    d[item['key']].append(item)

defaultdict 会确保正确地初始化列表。


4

你没有使用默认值工厂。如果你只是对键进行赋值,而不是尝试检索尚未在字典中的键,则不会看到任何区别。

默认值工厂(传递给defaultdict()的第一个参数)并不是类型声明。它实际上是在你尝试访问尚未在字典中的键时被调用

>>> from collections import defaultdict
>>> def demo_factory():
...     print('Called the factory for a missing key')
...     return 'Default value'
...
>>> d = defaultdict(demo_factory)
>>> list(d)  # list the keys
[]
>>> d['foo']
Called the factory for a missing key
'Default value'
>>> list(d)
['foo']
>>> d['foo']
'Default value'
>>> d['bar'] = 'spam'  # assignment is not the same thing
>>> list(d)
['foo', 'bar']
>>> d['bar']
'spam'    

只有在我第一次尝试访问键'foo'时,工厂才会被调用以生成默认值,然后将其存储在字典中供将来访问。

因此,在您的不同示例中,每个示例之间变化的是为每个示例生产的默认值。您从未访问过此功能,因为您直接分配给了'one'键。

如果您访问不存在的键,则分别创建一个值为0的整数、空列表或None


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接