摘要:項目地址迭代器與生成器迭代器與生成器是中比較常用又很容易混淆的兩個概念,今天就把它們梳理一遍,并舉一些常用的例子。生成器前面說到創(chuàng)建迭代器有種方法,其中第三種就是生成器。
項目地址:https://git.io/pytips
迭代器與生成器迭代器(iterator)與生成器(generator)是 Python 中比較常用又很容易混淆的兩個概念,今天就把它們梳理一遍,并舉一些常用的例子。
for 語句與可迭代對象(iterable object):
for i in [1, 2, 3]: print(i)
1 2 3
obj = {"a": 123, "b": 456} for k in obj: print(k)
b a
這些可以用在 for 語句進行循環(huán)的對象就是可迭代對象。除了內置的數(shù)據(jù)類型(列表、元組、字符串、字典等)可以通過 for 語句進行迭代,我們也可以自己創(chuàng)建一個容器,包含一系列元素,可以通過 for 語句依次循環(huán)取出每一個元素,這種容器就是迭代器(iterator)。除了用 for 遍歷,迭代器還可以通過 next() 方法逐一讀取下一個元素。要創(chuàng)建一個迭代器有3種方法,其中前兩種分別是:
為容器對象添加 __iter__() 和 __next__() 方法(Python 2.7 中是 next());__iter__() 返回迭代器對象本身 self,__next__() 則返回每次調用 next() 或迭代時的元素;
內置函數(shù) iter() 將可迭代對象轉化為迭代器
# iter(IterableObject) ita = iter([1, 2, 3]) print(type(ita)) print(next(ita)) print(next(ita)) print(next(ita)) # Create iterator Object class Container: def __init__(self, start = 0, end = 0): self.start = start self.end = end def __iter__(self): print("[LOG] I made this iterator!") return self def __next__(self): print("[LOG] Calling __next__ method!") if self.start < self.end: i = self.start self.start += 1 return i else: raise StopIteration() c = Container(0, 5) for i in c: print(i)
1 2 3 [LOG] I made this iterator! [LOG] Calling __next__ method! 0 [LOG] Calling __next__ method! 1 [LOG] Calling __next__ method! 2 [LOG] Calling __next__ method! 3 [LOG] Calling __next__ method! 4 [LOG] Calling __next__ method!
創(chuàng)建迭代器對象的好處是當序列長度很大時,可以減少內存消耗,因為每次只需要記錄一個值即刻(經(jīng)??吹饺藗兘榻B Python 2.7 的 range 函數(shù)時,建議當長度太大時用 xrange 更快,在 Python 3.5 中已經(jīng)去除了 xrange 只有一個類似迭代器一樣的 range)。
生成器前面說到創(chuàng)建迭代器有3種方法,其中第三種就是生成器(generator)。生成器通過 yield 語句快速生成迭代器,省略了復雜的 __iter__() & __next__() 方式:
def container(start, end): while start < end: yield start start += 1 c = container(0, 5) print(type(c)) print(next(c)) next(c) for i in c: print(i)
0 2 3 4
簡單來說,yield 語句可以讓普通函數(shù)變成一個生成器,并且相應的 __next__() 方法返回的是 yield 后面的值。一種更直觀的解釋是:程序執(zhí)行到 yield 會返回值并暫停,再次調用 next() 時會從上次暫停的地方繼續(xù)開始執(zhí)行:
def gen(): yield 5 yield "Hello" yield "World" yield 4 for i in gen(): print(i)
5 Hello World 4
Python 3.5 (準確地說應該是 3.3 以后)中為生成器添加了更多特性,包括 yield from 以及在暫停的地方傳值回生成器的 send()等,為了保持簡潔這里就不深入介紹了,有興趣可以閱讀官方文檔說明以及參考鏈接2。
參考Iterators & Generators
How the heck does async/await work in Python 3.5?
Python"s yield from
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37798.html
摘要:項目地址引入了語句與上下文管理器類型,其主要作用包括保存重置各種全局狀態(tài),鎖住或解鎖資源,關閉打開的文件等。了解了語句的執(zhí)行過程,我們可以編寫自己的上下文管理器。生成器的寫法更簡潔,適合快速生成一個簡單的上下文管理器。 項目地址:https://git.io/pytips Python 2.5 引入了 with 語句(PEP 343)與上下文管理器類型(Context Manager ...
摘要:項目地址列表推導中提到的方法可以通過簡化的語法快速構建我們需要的列表或其它可迭代對象,與它們功能相似的,還提供列表推導的語法。 項目地址:https://git.io/pytips 0x03 - Python 列表推導 0x02 中提到的 map/filter 方法可以通過簡化的語法快速構建我們需要的列表(或其它可迭代對象),與它們功能相似的,Python 還提供列表推導(List C...
摘要:借鑒了中的某些迭代器的構造方法,并在中實現(xiàn)該模塊是通過實現(xiàn),源代碼。 項目地址:https://git.io/pytips 0x01 介紹了迭代器的概念,即定義了 __iter__() 和 __next__() 方法的對象,或者通過 yield 簡化定義的可迭代對象,而在一些函數(shù)式編程語言(見 0x02 Python 中的函數(shù)式編程)中,類似的迭代器常被用于產(chǎn)生特定格式的列表(或序列)...
項目地址:https://git.io/pytips Python 的修飾器是一種語法糖(Syntactic Sugar),也就是說: @decorator @wrap def func(): pass 是下面語法的一種簡寫: def func(): pass func = decorator(wrap(func)) 關于修飾器的兩個主要問題: 修飾器用來修飾誰 誰可以作為修飾器...
摘要:項目地址提供兩種內置排序方法,一個是只針對的原地排序方法,另一個是針對所有可迭代對象的非原地排序方法。 項目地址:https://git.io/pytips Python 提供兩種內置排序方法,一個是只針對 List 的原地(in-place)排序方法 list.sort(),另一個是針對所有可迭代對象的非原地排序方法 sorted()。 所謂原地排序是指會立即改變被排序的列表對象,就...
閱讀 3151·2023-04-26 02:33
閱讀 3106·2023-04-25 21:33
閱讀 913·2021-09-02 09:56
閱讀 2930·2019-08-30 15:44
閱讀 2464·2019-08-30 13:15
閱讀 1038·2019-08-30 13:04
閱讀 1638·2019-08-29 15:09
閱讀 3968·2019-08-26 18:26