91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python生成器與迭代器的區別是什么

發布時間:2020-09-09 13:53:41 來源:億速云 閱讀:224 作者:小新 欄目:編程語言

小編給大家分享一下python生成器與迭代器的區別是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

對于list、string、tuple、dict等這些容器對象,使用for循環遍歷是很方便的。在后臺for語句對容器對象調用iter()函數。iter()是python內置函數。 iter()函數會返回一個定義了next()方法的迭代器對象,它在容器中逐個訪問容器內的元素。next()也是python內置函數。在沒有后續元素時,next()會拋出一個StopIteration異常,通知for語句循環結束。

python生成器與迭代器的區別是什么

迭代器

迭代器是用來幫助我們記錄每次迭代訪問到的位置,當我們對迭代器使用next()函數的時候,迭代器會向我們返回它所記錄位置的下一個位置的數據。實際上,在使用next()函數的時候,調用的就是迭代器對象的_next_方法(Python3中是對象的_next_方法,Python2中是對象的next()方法)。所以,我們要想構造一個迭代器,就要實現它的_next_方法。但這還不夠,python要求迭代器本身也是可迭代的,所以我們還要為迭代器實現_iter_方法,而_iter_方法要返回一個迭代器,迭代器自身正是一個迭代器,所以迭代器的_iter_方法返回自身self即可。

一些術語的解釋:

1,迭代器協議:對象需要提供next()方法,它要么返回迭代中的下一項,要么就引起一個StopIteration異常,以終止迭代。
2,可迭代對象:實現了迭代器協議對象。list、tuple、dict都是Iterable(可迭代對象),但不是Iterator(迭代器對象)。但可以使用內建函數iter() ,把這些都變成Iterable(可迭代器對象)。
3,for item in Iterable 循環的本質就是先通過iter()函數獲取可迭代對象Iterable的迭代器,然后對獲取到的迭代器不斷調用next()方法來獲取下一個值并將其賦值給item,當遇到StopIteration的異常后循環結束。

Python自帶容器對象案例:

# 隨便定義一個list
listArray=[1,2,3]
# 使用iter()函數
iterName=iter(listArray)
print(iterName)
# 結果如下:是一個列表list的迭代器
# <list_iterator object at 0x0000017B0D984278>
 
print(next(iterName))
print(next(iterName))
print(next(iterName))
print(next(iterName))#沒有迭代到下一個元素,直接拋出異常
# 1
# 2
# 3
# Traceback (most recent call last):
# File "Test07.py", line 32, in <module>
# StopIteration

Python中一個實現了_iter_方法和_next_方法的類對象,就是迭代器,如下案例是計算菲波那切數列的案例

class Fib(object):
 def __init__(self, max):
  super(Fib, self).__init__()
  self.max = max
 
 def __iter__(self):
  self.a = 0
  self.b = 1
  return self
 
 def __next__(self):
  fib = self.a
  if fib > self.max:
   raise StopIteration
  self.a, self.b = self.b, self.a + self.b
  return fib
 
# 定義一個main函數,循環遍歷每一個菲波那切數
def main():
 # 20以內的數
 fib = Fib(20)
 for i in fib:
  print(i)
 
# 測試
if __name__ == '__main__':
 main()

解釋說明:

在本類的實現中,定義了一個_iter_(self)方法,這個方法是在for循環遍歷時被iter()調用,返回一個迭代器。因為在遍歷的時候,是直接調用的python內置函數iter() ,由iter()通過調用_iter_(self)獲得對象的迭代器。有了迭代器,就可以逐個遍歷元素了。而逐個遍歷的時候,也是使用內置的next()函數通過調用對象的_next_(self)方法對迭代器對象進行遍歷。所以要實現_iter_(self)和_next_(self)這兩個方法。

而且因為實現了_next_(self)方法,所以在實現_iter_(self)的時候,直接返回self就可以。

總結一句話就是:

在循環遍歷自定義容器對象時,會使用python內置函數iter()調用遍歷對象的_iter_(self)獲得一個迭代器,之后再循環對這個迭代器使用next()調用迭代器對象的_next_(self) 。

注意點: _iter_(self)只會被調用一次,而_next_(self)會被調用 n 次,直到出現StopIteration異常。

生成器

作用:

延遲操作。也就是在需要的時候才產生結果,不是立即產生結果。

注意事項:

生成器是只能遍歷一次的。
生成器是一類特殊的迭代器。

分類:

第一類:生成器函數:還是使用 def 定義函數,但是,使用yield而不是return語句返回結果。yield語句一次返回一個結果,在每個結果中間,掛起函數的狀態,以便下次從它離開的地方繼續執行。

# 菲波那切數列
def Fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  yield b
  a, b = b, a + b
  n = n + 1
 return '親!沒有數據了...'
# 調用方法,生成出10個數來
f=Fib(10)
# 使用一個循環捕獲最后return 返回的值,保存在異常StopIteration的value中
while True:
 try:
  x=next(f)
  print("f:",x)
 except StopIteration as e:
  print("生成器最后的返回值是:",e.value)
  break

第二類:生成器表達式:類似于列表推導,只不過是把一對大括號[]變換為一對小括號()。但是,生成器表達式是按需產生一個生成器結果對象,要想拿到每一個元素,就需要循環遍歷。

如下案例加以說明:

# 一個列表
xiaoke=[2,3,4,5]
# 生成器generator,類似于list,但是是把[]改為()
gen=(a for a in xiaoke)
for i in gen:
 print(i)
#結果是:
2
3
4
5
# 為什么要使用生成器?因為效率。
# 使用生成器表達式取代列表推導式可以同時節省 cpu 和 內存(RAM)。
# 如果你構造一個列表(list)的目的僅僅是傳遞給別的函數,
# 比如 傳遞給tuple()或者set(), 那就用生成器表達式替代吧! 
#本案例是直接把列表轉化為元組
kk=tuple(a for a in xiaoke)
print(kk)
#結果是:
(2, 3, 4, 5) 
# python內置的一些函數,可以識別這是生成器表達式,外面有一對小括號,就是生成器
result1=sum(a for a in range(3))
print(result1)
# 列表推導式
result2=sum([a for a in range(3)])
print(result2)

區別:

生成器能做到迭代器能做的所有事,而且因為自動創建了 iter()和 next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表達式取代列表解析可以同時節省內存。除了創建和保存程序狀態的自動方法,當發生器終結時,還會自動拋出 StopIteration 異常。

看完了這篇文章,相信你對python生成器與迭代器的區別是什么有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙山县| 盐源县| 周口市| 搜索| 玉山县| 南昌市| 广灵县| 托里县| 大同市| 六枝特区| 定安县| 施秉县| 论坛| 汤原县| 札达县| 黎城县| 鲁甸县| 怀安县| 延津县| 惠水县| 旬阳县| 交口县| 铜山县| 临安市| 蓝山县| 江西省| 嵊州市| 洪泽县| 凤城市| 措勤县| 石门县| 伊春市| 石河子市| 柳州市| 安新县| 蕉岭县| 青冈县| 泾阳县| 连云港市| 高要市| 固阳县|