欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Python3中的迭代器和生成器及其區(qū)別

 更新時間:2018年10月09日 14:20:52   作者:miuric  
本篇將介紹Python3中的迭代器與生成器,描述可迭代與迭代器關(guān)系,并實現(xiàn)自定義類的迭代器模式。非常具有實用價值,需要的朋友可以參考下

介紹

本篇將介紹Python3中的迭代器與生成器,描述可迭代與迭代器關(guān)系,并實現(xiàn)自定義類的迭代器模式。

迭代的概念

上一次輸出的結(jié)果為下一次輸入的初始值,重復(fù)的過程稱為迭代,每次重復(fù)即一次迭代,并且每次迭代的結(jié)果是下一次迭代的初始值

注:循環(huán)不是迭代

while True: #只滿足重復(fù),因而不是迭代
print('====>')

 迭代器

1.為什么要有迭代器?

對于沒有索引的數(shù)據(jù)類型,必須提供一種不依賴索引的迭代方式。

2.迭代器定義:

迭代器:可迭代對象執(zhí)行__iter__方法,得到的結(jié)果就是迭代器,迭代器對象有__next__方法

它是一個帶狀態(tài)的對象,他能在你調(diào)用next()方法的時候返回容器中的下一個值,任何實現(xiàn)了__iter__和__next__()方法的對象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一個值,如果容器中沒有更多元素了,則拋出StopIteration異常

可迭代的(iterable)

Python標(biāo)準(zhǔn)庫中存在著一些可迭代對象,例如:list, tuple, dict, set, str等。

可以對這些迭代對象,進(jìn)行for-in等迭代操作,例如:

for s in "helloworld":
  print(s)

編譯器若想迭代一個對象a,則會自動調(diào)用iter(a)獲取該對象的迭代器(iterator),如果iter(a)拋出異常,則對象a不可迭代。

判斷對象是否可迭代

原生函數(shù)iter(instance) 可以判斷某個對象是否可迭代,它的工作流程大概分為以下3個步驟:

  • 檢查對象instance是否實現(xiàn)了__iter__方法,并調(diào)用它獲取返回的迭代器(iterator)。
  • 如果對象沒有實現(xiàn)__iter__方法,但是實現(xiàn)了__getitem__方法,Python會生成一個迭代器。
  • 如果上述都失敗,則編譯器則拋出TypeError錯誤,‘xxx' Object is not iterable。

自定義類實現(xiàn)__iter__方法

根據(jù)第一條,我們自定義類Iter1實現(xiàn)__iter__方法使該類的對象可迭代。

class Iter1:
  def __init__(self, text):
    self.text = text

  def __iter__(self):
    return iter(self.text)

iter1 = Iter1("hello")
for s in iter1:
  print(s)

Iter1類實現(xiàn)了__iter__方法,通過iter()調(diào)用,得到可迭代對象text的迭代器并返回,實現(xiàn)了迭代器協(xié)議,因此可以通過for-in等方式對該對象進(jìn)行迭代。

第二條通常都是針對Python中的序列(sequence)而定義,例如list,為了實現(xiàn)sequence協(xié)議,需要實現(xiàn)__getitem__方法。

class Iter2:
  def __init__(self, sequence):
    self.sequence = sequence

  def __getitem__(self, item):
    return self.sequence[item]


iter2 = Iter2([1, 2, 3, 4])
for s in iter2:
  print(s)

實際上,為了避免版本后序改動,Python標(biāo)準(zhǔn)庫中的序列除了實現(xiàn)了__getitem__方法,也實現(xiàn)了__iter__方法,因此我們在定義序列時也應(yīng)實現(xiàn)__iter__。

綜上,如果顯示判斷某個對象是否可迭代,應(yīng)該調(diào)用iter(instance)是否拋出異常,因為只實現(xiàn)了__getitem__的序列也是可迭代的(例子中Iter2的對象是可迭代的,但isinstance(iter2, abc.Iterator)返回結(jié)果是False)。同時,如果在調(diào)用iter后進(jìn)行迭代操作不必顯示判斷,可以用try/except方式包裝代碼塊。

iterable vs iterator(可迭代vs迭代器)

iterable定義

任何可以由原生函數(shù)iter獲取到迭代器的對象
任何實現(xiàn)了__iter__方法并返回迭代器的對象
所有的序列(實現(xiàn)了__getitem__)

Python通過獲取到可迭代對象的迭代器(iterator)實現(xiàn)迭代,例如for-in的實現(xiàn)其實是在內(nèi)部獲取到了迭代器進(jìn)行操作。for-in機制可以理解為下述代碼:

s = 'hello'
it = iter(s)
while (True):
  try:
    print(next(it))
  except StopIteration:
    del it
    break

StopIteration異常將在迭代器耗盡后被拋出,for-in、生成式(comprehension)、元組解壓(tuple unpacking)等迭代操作都會處理并這個異常。

迭代器是個迭代值生產(chǎn)工廠,它保存迭代狀態(tài),并通過next()函數(shù)產(chǎn)生下一個迭代值。實現(xiàn)迭代器需要實現(xiàn)以下兩個方法:

__iter__
返回self

__next__
返回下一個可用的元素,如果無可用元素則拋出StopIteration異常

迭代器實現(xiàn)__iter__,因此所有的迭代器都是可迭代的,下圖展示了iterable和iterator的結(jié)構(gòu)。

迭代器模式

實現(xiàn)一個自定義的迭代器模式需要兩個類,分別為實現(xiàn)了__iter__方法的類和通過__iter__返回的迭代器實例類(實現(xiàn)了__iter__和__next__方法)。下面例子簡單實現(xiàn)了上述功能。

class IterText:
  def __init__(self, text):
    self.text = text

  def __iter__(self):
    return IteratorText(self.text)


class IteratorText:
  def __init__(self, text):
    self.text = text
    self.index = 0

  def __iter__(self):
    return self

  def __next__(self):
    try:
      letter = self.text[self.index]
    except IndexError:
      raise StopIteration
    self.index += 1
    return letter

text = IterText("hey")
for l in text:
  print(l)

可迭代的IterText實現(xiàn)了__iter__方法,返回了迭代器IteratorText實例。IteratorText實現(xiàn)了__next__方法返回下一個迭代元素直到拋出異常,同時IteratorText實現(xiàn)了__iter__方法返回自身對象用于迭代。
這里的IterText和IteratorText很容易混淆,如果在IterText中實現(xiàn)了__next__方法并將__iter__中返回自身實例self也可以實現(xiàn)上述功能,但通??傻鷮ο蠛偷鲬?yīng)當(dāng)分開,這樣在可迭代對象中的__iter__中可以返回不同的迭代器對象,使功能獨立。

生成器(generator)

通過上述文章說明,迭代器通過next()不斷產(chǎn)出下一個元素直到迭代器耗盡,而Python中的生成器可以理解為一個更優(yōu)雅的迭代器(不需要實現(xiàn)__iter__和__next__方法),實現(xiàn)了迭代器協(xié)議,它也可以通過next()產(chǎn)出元素。
Python中的生成器主要分為兩種類型:

生成器函數(shù)(generator function)返回得到的生成器:

包含yield關(guān)鍵字的函數(shù)稱為生成器函數(shù)

def gen_func():
  yield 1
  yield 2
  yield 3
g = gen_func()

生成器表達(dá)式(generator expression)返回得到的生成器

g = (i for i in (1, 2, 3))

我們可以利用生成器進(jìn)行迭代操作:

for e in g:
  print(e)
  
## 生成器g已被耗盡,如果需要重新迭代需要重新獲得新的生成器對象
g = gen_func()
for e in g:
  print(e)

利用生成器代替可迭代中的__iter__迭代器

在迭代器模式章節(jié)中,我們在可迭代IterText中的__iter__返回迭代器IteratorText實例,然而使用生成器的方式會使代碼更加優(yōu)雅。

class IterText:
  def __init__(self, text):
    self.text = text

  def __iter__(self):
    for letter in self.text:
      yield letter

因為yield存在于__iter__,因此__iter__變成了生成器函數(shù),調(diào)用它測返回一個生成器,同時生成器又實現(xiàn)了迭代器協(xié)議,因此IterText滿足了可迭代的需求。

總結(jié)

本篇介紹了Python中的可迭代(iterable)、迭代器(iterator)以及它們的關(guān)系,并講述了迭代器模式的實現(xiàn),同時通過Python中的生成器完善了迭代器模式。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python實戰(zhàn)之異步獲取中國天氣信息

    Python實戰(zhàn)之異步獲取中國天氣信息

    這篇文章主要介紹了如何利用Python爬蟲異步獲取天氣信息,用的API是中國天氣網(wǎng)。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動手試一試
    2022-03-03
  • pandas讀取HTML和JSON數(shù)據(jù)的實現(xiàn)示例

    pandas讀取HTML和JSON數(shù)據(jù)的實現(xiàn)示例

    Pandas可以直接讀取html和JSON數(shù)據(jù),本文就來介紹一下pandas讀取HTML和JSON數(shù)據(jù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),感興趣的可以了解一下
    2024-01-01
  • Eclipse和PyDev搭建完美Python開發(fā)環(huán)境教程(Windows篇)

    Eclipse和PyDev搭建完美Python開發(fā)環(huán)境教程(Windows篇)

    這篇文章主要介紹了Eclipse和PyDev搭建完美Python開發(fā)環(huán)境教程(Windows篇),具有一定的參考價值,感興趣的小伙伴可以了解一下。
    2016-11-11
  • python解釋器安裝教程的方法步驟

    python解釋器安裝教程的方法步驟

    這篇文章主要介紹了python解釋器安裝教程的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 跟老齊學(xué)Python之玩轉(zhuǎn)字符串(1)

    跟老齊學(xué)Python之玩轉(zhuǎn)字符串(1)

    本文主要講訴了字符串的定義,變量鏈接到字符串,以及對字符串的簡單操作,都是些非常基礎(chǔ)的東西,適合零基礎(chǔ)的Pythoner學(xué)習(xí),覺得有用的話,多鼓鼓掌吧
    2014-09-09
  • 淺析python中的二元嵌套列表分組

    淺析python中的二元嵌套列表分組

    這篇文章主要來和大家一起討論一下Python中的二元嵌套列表,并將每個嵌套列表元素相對于其其他索引元素進(jìn)行分組,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-09-09
  • matplotlib繪制雷達(dá)圖的基本配置(萬能模板案例)

    matplotlib繪制雷達(dá)圖的基本配置(萬能模板案例)

    本文主要介紹了matplotlib繪制雷達(dá)圖的基本配置(萬能模板案例),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Python實現(xiàn)繪圖散點圖(scatter)

    Python實現(xiàn)繪圖散點圖(scatter)

    這篇文章主要介紹了Python實現(xiàn)繪圖散點圖方式(scatter),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Tensorflow中使用tfrecord方式讀取數(shù)據(jù)的方法

    Tensorflow中使用tfrecord方式讀取數(shù)據(jù)的方法

    這篇文章主要介紹了Tensorflow中使用tfrecord方式讀取數(shù)據(jù)的方法,適用于數(shù)據(jù)較多時,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Python矩陣常見運算操作實例總結(jié)

    Python矩陣常見運算操作實例總結(jié)

    這篇文章主要介紹了Python矩陣常見運算操作,結(jié)合實例形式總結(jié)分析了Python矩陣的創(chuàng)建以及相乘、求逆、轉(zhuǎn)置等相關(guān)操作實現(xiàn)方法,需要的朋友可以參考下
    2017-09-09

最新評論