2012-02-23 60 views
6

我找不到什麼在這個非常簡單的程序正在進行簡潔的信息:Python變量處理,我不明白它

print 'case 1' 
# a and b stay different 
a = [1,2,3] 
b = a 
b = [4,5,6] 

print 'a =',a 
print 'b =',b 

print 
print 'case 2' 
# a and b becomes equal 
a = [1,2,3] 
b = a 
b[0] = 4 
b[1] = 5 
b[2] = 6 

print 'a =',a 
print 'b =',b 
print 

print 'case 3' 
# a and b stay different now 
a = [1,2,3] 
b = a[:] 
b[0] = 4 
b[1] = 5 
b[2] = 6 
print 'a =',a 
print 'b =',b 
print 

print 'case 4' 
# now the funny thing 
a=[1,2,[3]] 
b=a[:] 
b[0] = 4 
b[1] = 5 
b[2][0] = 6 # this modifies b and a!!! 

這個簡單的測試的輸出是:

case 1 
a = [1, 2, 3] 
b = [4, 5, 6] 

case 2 
a = [4, 5, 6] 
b = [4, 5, 6] 

case 3 
a = [1, 2, 3] 
b = [4, 5, 6] 

case 4 
a = [1, 2, [6]] 
b = [4, 5, [6]] 

我顯然不明白python如何處理每種情況。任何人都可以提供一個鏈接,以便我可以閱讀它,或者對發生的事情做一個簡短的解釋?

非常感謝。

回答

6

這裏有兩個重要的事情:

  • 變量只是標籤指向對象
  • 名單在Python可變和整數都沒有。

當您發現ab都被修改時,那是因爲它們都指向同一個對象。您可以使用id(a)id(b)來確認。

關於這些示例,請注意a[:]將創建一個新對象,它是a的副本。但是,這將是一個淺層副本,而不是深層副本。這解釋了爲什麼在示例4中,您仍然可以修改ab。它們指向不同的列表對象,但其中一個元素是另一個由它們共享的列表。

4

案例1:名稱b被反彈。

案例2:ab被綁定到相同的對象。

案例3:a的淺拷貝綁定到b。列表不同,但列表中的對象是相同的。

案例4:a的淺拷貝綁定到b,然後其中一個對象發生了變異。

重新結合不會突變,並且突變不會重新結合。

3
print 'case 1' 
# a and b stay different 
a = [1,2,3] 
b = a    #At this point 'b' and 'a' are the same, 
        #just names given to the list 
b = [4,5,6]  #At this point you assign the name 'b' to a different list 

print 'a =',a 
print 'b =',b 

print 
print 'case 2' 
# a and b becomes equal 
a = [1,2,3]  #At this point 'b' and 'a' are the same, 
        #just names given to the list 
b = a 
b[0] = 4   #From here you modify the list, since both 'a' and 'b' 
        #reference the same list, you will see the change in 'a' 
b[1] = 5 
b[2] = 6 


print 'case 3' 
# a and b stay different now 
a = [1,2,3] 
b = a[:]    #At this point you COPY the elements from 'a' into a new 
         #list that is referenced by 'b' 
b[0] = 4    #From here you modify 'b' but this has no connection to 'a' 
b[1] = 5 
b[2] = 6 
print 'a =',a 
print 'b =',b 
print 

print 'case 4' 
# now the funny thing 
a=[1,2,[3]] 
b=a[:]   #At this point you COPY the elements from 'a' into a new 
       #list that is referenced by 'b' 
b[0] = 4  #Same as before 
b[1] = 5 
b[2][0] = 6 # this modifies b and a!!! #Here what happens is that 'b[2]' holds 
       #the same list as 'a[2]'. Since you only modify the element of that 
       #list that will be visible in 'a', try to see it as cases 1/2 just 
       #'recursively'. If you do b[2] = 0, that won't change 'a' 
+0

傑出的解釋。這對我非常有幫助,尤其是列表[:]聲明。謝謝。 – trinkner 2017-12-03 21:27:32