[英]reduce not working for collections.defaultdict?
Why is reduce()
is not working with a defaultdict
object in the following case: 在以下情况下,为什么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'
The above reduce
is equivalent to d[1][2]
, so I expected 0
, ie the default return value as output but I got a NoneType
exception instead. 上面的reduce
等效于d[1][2]
,所以我期望0
,即默认返回值作为输出,但是我得到了NoneType
异常。
If I use d[1][2]
it works fine as shown below: 如果我使用d[1][2]
则如下所示:
>>> d[1][2]
0
Am I doing anything wrong? 我做错什么了吗?
dict.get()
returns None
if a key is not present, even for a defaultdict
object . 如果不存在键, 即使对于defaultdict
对象 , dict.get()
将返回None
。
That's because the job of dict.get()
is to return a default value instead when a key is missing. 这是因为dict.get()
的工作是在缺少键时返回默认值。 If it didn't you'd never be able to return a different default (the second argument to dict.get()
): 如果没有,您将永远无法返回不同的默认值( dict.get()
的第二个参数):
>>> from collections import defaultdict
>>> d = defaultdict(lambda: defaultdict(int))
>>> d.get(1, 'default')
'default'
In other words, your reduce(dict.get, ..)
function is not the equivalent of the d[1][2]
expression. 换句话说,您的reduce(dict.get, ..)
函数不等同于d[1][2]
表达式。 It is the equivalent of d.get(1).get(2)
, which fails the exact same way: 它等效于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'
Use dict.__getitem__
instead if you want to rely on the auto-insertion behaviour: 如果要依赖自动插入行为,请使用dict.__getitem__
:
>>> reduce(dict.__getitem__, [1,2], d)
0
The expression d[1]
translates directly to d.__getitem__(1)
. 表达式d[1]
直接转换为d.__getitem__(1)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.