减少不适用于 collections.defaultdict?

reduce not working for collections.defaultdict?

为什么 reduce() 在以下情况下不能使用 defaultdict 对象:

>>> from collections import defaultdict
>>> d = defaultdict(lambda: defaultdict(int))
>>> reduce(dict.get, [1,2], d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'get' requires a 'dict' object but received a 'NoneType'

上面的reduce相当于d[1][2],所以我期望0,即默认的return值作为输出,但我得到了NoneType例外。

如果我使用 d[1][2] 它工作正常,如下所示:

>>> d[1][2]
0

我做错了什么吗?

dict.get() returns None 如果键不存在,即使是 defaultdict 对象.

那是因为 dict.get()job 是 return 一个默认值,而不是当一个键丢失时。如果没有,您将永远无法 return 一个 不同的 默认值(dict.get() 的第二个参数):

>>> from collections import defaultdict
>>> d = defaultdict(lambda: defaultdict(int))
>>> d.get(1, 'default')
'default'

换句话说,您的 reduce(dict.get, ..) 函数 不是 等同于 d[1][2] 表达式。它等效于 d.get(1).get(2),它以完全相同的方式失败:

>>> d = defaultdict(lambda: defaultdict(int))
>>> d.get(1).get(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'get'

如果您想依赖自动插入行为,请改用 dict.__getitem__

>>> reduce(dict.__getitem__, [1,2], d)
0

表达式 d[1] 直接转换为 d.__getitem__(1)