2015-09-18 24 views
1

为什么reduce()不与defaultdict对象在以下情况下工作:减少不能用于collections.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 

难道我做错了什么?

回答

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)

+0

为什么使用dict .__ getitem__而不是defaultdict .__ getitem__是正确的? – Hammerite

+0

@Hammerite:你可以使用; 'defaultdict'是'dict'的一个子类。 –

+0

完美!谢谢 –