簡體   English   中英

Python迭代器與索引

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM