[英]Python: list is not mutated after for loop
a =[1,2]
for entry in a:
entry = entry + 1
print a
列表不應該變異為[2,3]
嗎? 結果如[1,2]
。 為什么?
要修改原始列表,您可以這樣做:
a =[1,2]
for x in range(len(a)):
a[x] = a[x] + 1
print a
或者您可以將for循環更改為“oneliner”,如下所示:
a =[1,2]
a = [x + 1 for x in a]
print a
兩種方法的輸出:
[2, 3]
方法之間的區別是第一個修改列表,而第二個創建新列表。
不,因為當你執行entry = entry + 1
你創建一個新的整數對象並將其綁定到名稱entry
,綁定到該名稱的原始對象不受影響。
請記住,在Python中,整數對象是不可變的。 但是,如果a
包含可變對象(如列表),則可以執行以下操作:
a = [[1], [2]]
for entry in a:
entry += [1]
print a
然后在項目a
會突變:
產量
[[1, 1], [2, 1]]
請注意,如果您剛剛執行了entry = entry + [1]
那么a
將保持不變,因為簡單賦值將新對象綁定到名稱。
您可能會發現本文很有用: 關於Python名稱和值的事實和神話 ,由SO資深人士Ned Batchelder撰寫。
不,為什么要這樣?
entry
只是一個名稱,for循環分配給列表中的每個整數。 如果您隨后重新分配該名稱以指向其他整數,則列表無關緊要。
Python中的所有變量都包含存儲在某處的某個對象的引用(即指針)。 甚至整數都是對象。 賦值將指針更改為指向另一個對象,它不會修改指向的項目。
當你這樣做時:
a = [1, 2]
for entry in a:
entry = entry + 1
第一次循環時, entry
被制成指向整數1
,因為這是第一個元素a
(已知為a[0]
指向。
現在,整數1
不存儲在列表本身中,並且entry
不是指向列表中的槽的指針。 相反, entry
和a[0]
指向同一個對象,整數1
。
當您執行entry = entry + 1
(或只是entry += 1
)時, entry
將更改為指向整數2
。 但是, a[0]
不會更改,因為您沒有更改它。 它仍然指向整數1
。
在遍歷迭代時修改列表的Pythonic方法是使用enumerate()
。 這為您提供了索引(您需要修改列表項) 和列表中的值。
for index, entry in enumerate(a):
a[index] += 1
這里您實際上並沒有使用現有元素值,因此您也可以使用range
:
for index in range(len(a)):
a[index] += 1
另一種方法是使用切片分配和生成器表達式。 這將替換列表的全部內容:
a[:] = (entry + 1 for entry in a)
這樣做的好處是,如果列表a
還有其他名稱,則通過其他名稱可以看到更改的列表。 如果這不是你想要的,你也可以這樣做:
a = [entry + 1 for entry in a]
這將創建與更新的值一個新的列表,使a
指向它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.