[英]Python Iterators vs Indexing
在編寫函數時,嘗試兩種方法時遇到了一些有趣的事情。 一種方法使用索引,另一種方法使用迭代器:
索引方法:
A = [1,1,1,1]
def flipBits(A):
for i in range(len(A)):
if A[i] == 1:
A[i] = 0
else:
A[i] = 1
return A
>>> flipBits(A)
[0, 0, 0, 0]
迭代器方法:
A = [1,1,1,1]
def flipBits(A):
for bit in A:
if bit == 1:
bit = 0
else:
bit = 1
return A
>>> flipBits(A)
[1, 1, 1, 1]
如果我沒記錯的話,迭代器只是指向某些數據的指針的副本。 因此,當我嘗試將位設置為某項內容時,它僅設置副本,而不是列表的實際元素。
這個對嗎? 還有什么我應該知道的嗎? 謝謝。
如果我沒記錯的話,迭代器只是指向某些數據的指針的副本。
這是正確的,但並非完全正確。 主要的困惑是您沒有直接在第二個代碼塊中處理任何迭代器。 目前正在使用一個迭代器(里面for
循環),並有一個參考(即指針)的一些數據,但它們不是一回事。 bit
變量僅獲得對迭代器產生的值的引用。 不是迭代器本身。
您可以編寫自己的for
循環版本,顯式處理迭代器。 不用for bit in A:
,您將擁有:
_iterator = iter(A)
while True:
try:
bit = next(_iterator)
except StopIteration:
break
# body of the for loop goes here!
del _iterator
注意,該bit
在循環的每個周期都得到分配的值。 如果稍后再分配它(在原始循環的主體中),則原始值或它來自的列表都不會被修改。
您可能會在第一個代碼的稍微修改后的版本中看到類似的情況:
def flipBits(A):
for i in range(len(A)):
bit = A[i]
if bit == 1:
bit = 0
else:
bit = 1
return A
出於與您的代碼的for
循環版本相同的原因,該版本不會修改A
重新綁定bit
(這是一個局部變量)與重新綁定A[i]
並不相同,即使它們都引用了相同的值。
請注意,如果你沒有需要修改A
到位,更“Python化”的方式來解決這個問題是建立在它的翻轉位一個新的列表,使用列表理解:
def flipBits(A):
return [1-bit for bit in A] # you could also use "0 if bit == 1 else 1" instead of 1-bit
使用for
循環時,將創建一個新的引用變量,該變量依次設置為序列中的每個對象。
使用=
,它將左側的引用設置為右側的對象。
在第一種情況下, A[i]
是對列表元素的直接引用,因此列表將得到更新。
在第二種情況下, b
是與列表分開的引用; 它是由for
循環創建的。 更新它不會更改原始列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.