【问题标题】:Difference between defaultdict(lambda:None) and defaultdict(int)defaultdict(lambda:None) 和 defaultdict(int) 之间的区别
【发布时间】:2023-03-26 02:45:02
【问题描述】:
TYPE lambda 与defaultdict 一起使用时究竟做了什么?我有这个例子,即使 int、list 和 lambda 作为参数也能正常工作:
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字典并不关心传入的参数是什么类型。
【问题讨论】:
标签:
python
lambda
defaultdict
【解决方案1】:
您的示例仅在您访问未明确添加到字典中的键时才有意义:
>>> 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 将确保正确初始化列表。
【解决方案2】:
您没有使用默认值工厂。如果您所做的只是分配给键,而不是尝试检索字典中还没有的键,那么您不会看到任何区别。
默认值工厂(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。