爲什麼說:Python中的變量複製是如何工作的?
>>> a = 1
>>> b = a
>>> a = 2
>>> print(a)
2
>>> print(b)
1
...但:
>>> a = [3, 2, 1]
>>> b = a
>>> a.sort()
>>> print(b)
[1, 2, 3]
我的意思是,爲什麼變量真正複製和迭代器只是引用?
爲什麼說:Python中的變量複製是如何工作的?
>>> a = 1
>>> b = a
>>> a = 2
>>> print(a)
2
>>> print(b)
1
...但:
>>> a = [3, 2, 1]
>>> b = a
>>> a.sort()
>>> print(b)
[1, 2, 3]
我的意思是,爲什麼變量真正複製和迭代器只是引用?
變量不是「真正複製」的。變量是對象的名稱,賦值運算符將名稱綁定到運算符右側的對象。更詳細地說:
>>> a = 1
表示「使a
的名稱引用對象1
」。
>>> b = a
的意思是「使b
名稱指目前由a
所指的對象。這是1
。
>>> a = 2
的意思是‘使a
名字指的是對象2
。’這有哪個對象沒有影響其他任何事指1
現指,如b
。
在你的第二個例子,既a
和b
是指同一個列表對象名稱。a.sort()
突變了該對象,並且由於這兩個變量引用了相同的對象,所以在兩個名稱下都可以看到突變的效果。
另請參閱關於這些答案的更詳細和更詳細的討論:http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference和http:// stackoverflow。com/questions/534375/passing-values-in-python –
我認爲它也值得我們對可變性做一個簡短的解釋,並說爲什麼,比如說a + = 1在b和a都不會改變'b'如果a和b都是列表,則'a + = [1]'將注意到 –
將分配的變量看作指向保存值的內存位置的指針。您實際上可以使用id
獲取內存位置。
a = 1
b = a
>>> id(a)
4298171608
>>> id(b)
4298171608 # points to the same memory location
a = 2
>>> id(a)
4298171584 # memory location has changed
做與您的清單例子一樣,你可以看到,這兩個其實都是同一個對象上進行操作,但不同的變量都指向同一個內存位置。
a = [3, 2, 1]
b = a
a.sort()
>>> id(a)
4774033312
>>> id(b)
4774033312 # Same object
請注意,返回內存位置的'id'是一個實現細節 - 對於常見的C python實現是true,但並不保證在所有實現中都是true。可靠的是,如果兩個對象的id相同,則對象是相同的。什麼'id'意味着像整數和字符串這樣的不可變對象是一個更復雜的問題 - 通常你不應該關心什麼,因爲它們是不可變的。 –
在您的第一個示例中,您已將b值設爲a後重新分配了a的值。所以a和b帶有不同的值。
如果您已將一個新的排序列表重新分配,而不是將其排序,則在第二個示例中也會發生同樣的情況。
a = [3,2,1]
b = a
a.sort()
print b
[1,2,3]
但是......
a = [3,2,1]
b = a
sorted(a)
print b
[3,2,1]
在我看來,這是學習Python中最難的部分之一:學習要告訴你,當*之間的差異以現有對象並修改它*和當你*取一個現有的名字並且指向一個不同的對象時* – turbulencetoo
@turbulencetoo:很簡單。這裏沒有任何例子*複製*對象。對象可能有多個名稱。名稱可能在不同的時間涉及不同的對象。 [這張圖片可能提供了一個見解](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#python-has-names) – jfs