2015-07-03 69 views
4

我想了解如何將列表作爲參數傳遞給函數時進行處理。所以我所做的是以下幾點:傳遞給函數時列表發生了什麼?

我初始化列表:

ll = [1,2,3,4] 

和定義一個函數:

def Foo(ar): 
    ar += [11] 

我通過列表的功能:

Foo(ll) 

當我打印它時,我得到:

print ll # [1, 2, 3, 4, 11] #case(1) 

到目前爲止好。

現在我爲了重新設置列表,使得它只有一個元素修飾功能:

def Foo(ar): 
    ar = [11] 

我回憶的語法:

Foo(ll) 

,當我重新打印,它導致在同一個列表中:

print ll # [1, 2, 3, 4] # case(2) 

我以爲列表通過作爲參考;所以無論我們對函數內的列表做什麼都會改變從主程序傳來的原始函數。因此,對於案例(2)我期待以下結果:

print ll # [11] # case(2) expected result 

我在這裏錯過了什麼嗎?

+0

'ar = [11]'將名稱分配給**完全不同的對象**。如果要替換列表的全部內容,請嘗試'ar [:] = [11]'。 – jonrsharpe

+3

我發現你選擇名稱和值('ll'和'11')令人不安... – rodrigo

+0

對於名稱和值的選擇,我很抱歉。 – rnels12

回答

7

ar += [11]不是只是一個任務。這是一個方法調用(該方法稱爲:__iadd__)。當Python執行該行時,它會調用該方法,然後將ar賦值給結果。 list__iadd__方法修改當前的list

ar = [11]分配,因此它只是改變了當地的名ar的價值。但函數內的ar名稱與ll變量的值之間沒有關聯。

你可能想是這樣的:

ar[:] = [11] 
+0

嚴格地說,'ar + = [11]'實際上仍然是一項任務;它需要像'ar =(1,2,3); ar + =(11,)'工作。 – user2357112

+0

@ user2357112你說得對,我簡直太簡單了。修訂。 – Bakuriu

+0

感謝您的幫助。我想我現在明白了。 – rnels12

2

+=增強的任務做一些正常=分配沒有做。當您指定一個名字,像這樣:

ar = [11] 

這對ar名稱的操作。 ar以前提到的列表對象是不變的,所以當你做print ll以外的功能時,你會看到原來的列表。

當你

ar += [11] 

這並不完全等同於

ar = ar + [11] 

如果你沒有ar = ar + [11]ll將保持不變。但是,+=請求在可能的情況下,ar所引用的列表應通過修改其自身狀態來執行操作,而不是通過創建新列表來執行操作。由於列表是可變的,因此列表會自行修改以使其具有新的11元素,並且通過ll變量可以看到此更改。

+0

感謝您的解釋! – rnels12

5

您必須填寫對象的對象的名稱。 Python中的列表是可變對象,所以只要有引用就可以更改它們。

名稱只是對象的引用。請記住,從技術上講,在Python中不存在變量,只有名稱和對象,而且對象與名稱綁定。

因此,考慮到這一點,讓我們來看看你的代碼:

def Foo1(ar): 
    ar += [11] 

此函數接受一個列表,它綁定到本地名稱ar然後修改列表,添加新的價值。

然而,這其他代碼:

def Foo2(ar): 
    ar = [11] 

該函數將列表,綁定到ar名稱,然後用一個數值重新綁定名稱ar到一個新的列表。原始對象在此功能內部未經修改且不起泡。

然後,當你這樣做:

a = [1,2,3] 

然後調用:

Foo1(a) 

修改該列表中添加一個新的價值,而是:

Foo2(a) 

無助於價值的a

如果你想寫替換與另一個列表的所有內容的功能,你可以做到這一點:

def Foo3(a): 
    a[:] = [11] 

此代碼不重新綁定a但如果用替換內容修改的列表新的名單。

爲了進一步說明我的觀點,看看下面這個例子:

a = [] 
b = [] 
c = a 
a.append(1) 
b.append(2) 
c.append(3) 
print a 
print b 
print c 

它會打印:

[1, 3] 
[2] 
[1, 3] 

你能告訴爲什麼?

+0

是因爲名稱a&c現在用於引用同一個對象嗎? 感謝btw的解釋。 – rnels12

相關問題