python defaultdict:0 vs. int和[] vs list

bea*_*rdc 35 python collections defaultdict

传递intlambda: 0作为参数之间有什么区别吗?或者之间listlambda: []

看起来他们做同样的事情:

from collections import defaultdict
dint1 = defaultdict(lambda: 0)
dint2 = defaultdict(int)
dlist1 = defaultdict(lambda: [])
dlist2 = defaultdict(list)

for ch in 'abracadabra':
    dint1[ch] += 1
    dint2[ch] += 1
    dlist1[ch].append(1)
    dlist2[ch].append(1)

print dint1.items()
print dint2.items()
print dlist1.items()
print dlist2.items()
## -- Output: --
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
[('a', [1, 1, 1, 1, 1]), ('r', [1, 1]), ('b', [1, 1]), ('c', [1]), ('d', [1])]
[('a', [1, 1, 1, 1, 1]), ('r', [1, 1]), ('b', [1, 1]), ('c', [1]), ('d', [1])]
Run Code Online (Sandbox Code Playgroud)

但是,有什么情况下他们会有不同的行为,还是仅仅是一种符号差异?

Jef*_*ado 41

defaultdict需要的只是一个可调用的对象,它将返回在没有参数的情况下调用时应该用作默认值的对象.

如果您要调用int构造函数,它将返回0,如果您要调用lambda: 0,它将返回0.与列表相同.这里唯一的区别是构造函数将始终使用它的逻辑来创建对象.一个lambda,如果你选择这样做,你可以添加额外的逻辑.

例如,

# alternating between `0` and `[]`
from itertools import count
factory = lambda c=count(): 0 if next(c) % 2 else []
superdict = defaultdict(factory)
Run Code Online (Sandbox Code Playgroud)

  • 您可能还希望在线程安全性上看到这个答案:http://stackoverflow.com/questions/6319207/are-lists-thread-safe#answer-6319267使用`int`将是线程安全的,而使用`lambda:0 `不会. (3认同)
  • 对不起但是我不明白为什么`lambda:0`根据帖子引用不是线程安全的.根据`defaultdict` doc,工厂将在`dict .__ getitem __()`中调用.根据所提到的帖子,`dict .__ getitem __()`整体似乎保证是线程安全的.此外,工厂(`int`或`lambda:0`)只是在某处被调用的东西.似乎从一个地方转换到另一个地方,从任何地方调用,都不会破坏线程的安全性,前提是这两个工厂都不会修改任何超出自身的东西.@Carl (2认同)