在以下情况中,为什么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
,即默认返回值作为输出,但我得到了NoneType
例外。
如果我使用d[1][2]
,它可以正常工作,如下所示:
>>> d[1][2]
0
我做错了吗?
答案 0 :(得分:4)
dict.get()
会返回None
,即使对于defaultdict
对象也会返回。
这是因为dict.get()
的作业是在缺少密钥时返回默认值。如果没有,你将永远无法返回不同的默认值(第二个参数为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)
。