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

rva*_*rva 5 python lambda defaultdict

lambda当与 一起使用时,TYPE 究竟做了什么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
Run Code Online (Sandbox Code Playgroud)

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

pok*_*oke 6

您的示例仅在您访问未显式添加到字典中的键时才有意义:

>>> d = defaultdict(int)
>>> d['one']
0
>>> d = defaultdict(list)
>>> d['one']
[]
>>> d = defaultdict(lambda: None)
>>> d['one'] is None
True
Run Code Online (Sandbox Code Playgroud)

如您所见,使用默认字典将为您尝试访问的每个键提供默认值。该默认值是通过调用传递给构造函数的函数来获取的。因此传递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)
Run Code Online (Sandbox Code Playgroud)

它只是在访问时为每个字典项设置一个新的空列表,可以简化为:

d = defaultdict(list)
for item in some_source_for_items:
    d[item['key']].append(item)
Run Code Online (Sandbox Code Playgroud)

并且defaultdict将确保正确初始化列表。


Mar*_*ers 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'    
Run Code Online (Sandbox Code Playgroud)

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

因此,对于每个不同的示例,它们之间的不同之处在于将为每个示例生成的默认值。您永远不会访问此功能,因为您直接分配给了该'one'键。

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