2015-09-18 64 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

完美!謝謝 –