2011-05-25 47 views
11

當我在python 2.6奇怪行爲減少

reduce(lambda x,y: x+[y], [1,2,3],[]) 

我得到執行該代碼[1,2,3]如預期。 但是,當我執行這一個(我認爲這等同於以前的)

reduce(lambda x,y: x.append(y), [1,2,3],[]) 

我得到一個錯誤信息

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <lambda> 
AttributeError: 'NoneType' object has no attribute 'append' 

爲什麼的這兩行代碼沒有給予同樣的結果?

回答

14

x.append(y)不等同於x+[y]; append修改了一個列表,並返回任何內容,而x+[y]是一個返回結果的表達式。

+0

謝謝。現在我看到我應該更仔細地閱讀文檔。 – 2011-05-25 12:52:50

6

reduce的函數參數預計爲返回操作的結果。

x+[y]這樣做,而x.append(y)不(後者修改x並返回None)。

7

reduce調用函數並使用返回值作爲新結果。 append返回None,因此下一個append調用失敗。你可以寫

def tmpf(x,y): 
    x.append(y) 
    return x 
reduce(tmpf, [1,2,3], []) 

並得到正確的結果。但是,如果結果是與輸入大小相同的列表,則不需要reduce:reduce的結果通常應該是單個值。相反,使用map或者乾脆

[x for x in [1,2,3]] 
+2

我不會限定'tmpf'這種方式,因爲它有修改初始化程序的意想不到的副作用(最後一個參數爲'reduce')。 – NPE 2011-05-25 12:47:41

+0

@aix進一步警告不要使用'reduce'來產生一個列表。您可以在'tmpf'中插入'if len(x)== 0:x = []',但只強調'reduce'不適合這項工作。 – phihag 2011-05-25 12:54:40

0

只是爲了解釋的錯誤消息:

AttributeError: 'NoneType' object has no attribute 'append'

表達

reduce(lambda x,y: x.append(y), [1,2,3],[])

相當於

[].append(1).append(2).append(3)

由於[].append(1)不返回值,即它返回None它試圖執行(在第二步驟)

None.append(2)

這導致錯誤消息Nonetype object has no attribute append