可迭代物件、迭代器、生成器

码上的生活發表於2024-10-20

可迭代物件

如果實現了__iter__方法,就認為物件是可迭代的. 使用內建的iter函式可以獲取迭代器的物件.

  • 檢查物件x是否為迭代器,最好的方式是 呼叫 isinstance(x, abc.Iterator)
  • 序列都是可迭代的

迭代器(Iterator):

  • 迭代器是一個物件,它實現了 iter() 和 next() 兩個基本方法。
  • iter() 方法返回迭代器物件本身,用於判斷一個物件是否是一個迭代器。
  • next() 方法返回迭代器的下一個元素。
  • 迭代器允許你逐個訪問序列中的元素,直到所有元素都被訪問完畢。
  • 迭代器可以是任何實現了這兩個方法的物件,例如列表、元組、字典、集合等。

生成器(Generator):

  • 生成器是一種特殊的迭代器,它使用 yield 語句來產生值。
  • 生成器是使用函式定義的,當函式中出現 yield 語句時,它就變成一個生成器。
  • 當生成器函式被呼叫時,它返回一個生成器物件,而不是直接執行。生成器函式是生成器的工廠
  • 每次呼叫生成器的 next() 方法時,生成器函式會從上次 yield 語句處恢復執行,直到再次遇到 yield 語句或函式結束。
  • 生成器非常適合處理大資料集或無限序列,因為它不需要一次性將所有資料載入到記憶體中。

區別:

  • 記憶體使用:生成器通常比迭代器更節省記憶體,因為它們可以按需生成資料,而不是一次性生成所有資料。
  • 實現方式:迭代器可以由任何實現了 iter() 和 next() 方法的物件實現,而生成器是由包含 yield 語句的函式實現的。
  • 資料來源:迭代器通常用於訪問已經存在的資料集合,而生成器用於建立新的資料序列。
  • 函式和物件:迭代器是一個物件,而生成器是一個函式。
  • 迭代器也是可迭代物件,但是可迭代物件不是迭代器
  • 可迭代物件有一個__iter__方法,每次都例項化一個新的迭代器
    示例:
# 迭代器示例
my_list = [1, 2, 3, 4]
for item in my_list:
    print(item)

# 生成器示例
def my_generator():
    yield 1
    yield 2
    yield 3
    yield 4

gen = my_generator()
for item in gen:
    print(item)

在第一個示例中,my_list 是一個列表迭代器。在第二個示例中,my_generator 是一個生成器函式,每次呼叫時都會生成一個新值。

測試問題: 用迭代器和生成器實現列表的遍歷?

迭代器和生成器都可以用於遍歷列表,但是它們的實現方式不同。下面是兩種方法的示例:
使用迭代器遍歷列表
在 Python 中,列表(以及其他內建的集合型別,如元組、字典和集合)都是迭代器。你可以直接使用 for 迴圈來遍歷它們。

# 定義一個列表
my_list = [1, 2, 3, 4, 5]

# 使用迭代器(for 迴圈)遍歷列表
for item in my_list:
    print(item)

在這個例子中,my_list 本身就是一個迭代器,for 迴圈會自動呼叫 my_list 的 iter() 和 next() 方法來獲取列表中的元素。
使用生成器遍歷列表
生成器通常用於建立一個可以按需生成值的序列。如果你想要手動實現一個生成器來遍歷列表,你可以定義一個生成器函式。

# 定義一個生成器函式來遍歷列表
def list_generator(lst):
    for item in lst:
        yield item

# 建立一個列表
my_list = [1, 2, 3, 4, 5]

# 建立生成器物件
gen = list_generator(my_list)

# 使用生成器遍歷列表
for item in gen:
    print(item)

在這個例子中,list_generator 是一個生成器函式,它接受一個列表作為引數,並使用 yield 語句逐個產生列表中的元素。當你建立 gen 物件時,它會按照 list_generator 函式的邏輯來生成值。
雖然在這個特定的例子中,使用生成器來遍歷列表可能看起來有些多餘,因為列表本身就是一個迭代器,但生成器在處理大型資料集或需要按需生成資料時非常有用。例如,如果你有一個非常大的檔案列表,你可能不想一次性將它們全部載入到記憶體中,而是希望按需處理它們,這時生成器就會非常有用。

相關文章