2011-12-06 103 views
5

首先,我要像其他人一樣開始。我是python的新手。我的老師給我的問題:Python範圍可變vs不可變

def f(a, b, c): 
    a = 1 
    c = b 
    c[0] = 2 
a = 10 
b = [11, 12, 13] 
c = [13, 14, 15] 
f(a, b, c) 
print a, b, c 

它打印:

10 [2, 12, 13] [13, 14, 15] 

我明白,一個停留在10,因爲整數是不可改變的,但我不明白爲什麼b變爲和C不。

+2

我還要指出,這與數據類型是不可變的/不可變的無關。正如下面的答案指出的那樣,這是關於變量賦值。 [數據模型](http://docs.python.org/reference/datamodel.html)頁面討論了這種差異。 – Rob

+0

什麼是混淆你只是變量名,我猜。給函數外的不同名稱,即x,y,z;所以你想調用f(x,y,z),並打印x,y,z。我相信它不會那麼難看。 – Danny

回答

4
c = b 
c[0] = 2 

既然你設置c指向b,你可以很容易地做到這一點:

def f(a, b, unused): # notice c isn't in the parameter list 
    a = 1 
    c = b # c is declared here 
    c[0] = 2 # c points to b, so c[0] is b[0] 

現在很明顯,c總是一樣b,所以爲什麼不只是刪除它:

def f(a, b, unused): 
    a = 1 
    b[0] = 2 

而現在很明顯,你改變的b第一個元素,沒有做任何事情,以c,請記住,這在功能上與原始相同。

2

的關鍵是要了解變量的引擎蓋下指針:

def f(a, b, c): 
    a = 1 # a is a single scalar value, so no pointing involved 
    c = b # point the local "c" pointer to point to "b" 
    c[0] = 2 # change the 2nd value in the list pointed to by "c" to 2 

當你調用F(A,B,C),僅有B實際得到改變。函數實現中的「c」變量與函數外部的「c」實現不同。

0

a不保留10的值,因爲它是不可變的。它保留10的值,因爲當您在本地範圍f()中調用a = 1時,您將創建一個新變量。

當您在f()內部撥打c = b時,本地c成爲b表示的可變對象的本地引用。當您重新分配該可變對象中的值時,更改會反映到原始對象中。