生成器使您可以輕鬆地在python中建立迭代,從而減少編寫**。 本教程將向您介紹python生成器,它們的好處以及它們的工作方式。
生成器是乙個返回生成器物件的函式,您可以在該物件上呼叫next()
方法,這樣,每次呼叫它都會返回乙個值或下乙個值。 普通的python函式使用return
關鍵字返回值,但是生成器使用關鍵字yield
返回值。 這意味著任何包含yield
語句的python函式都是生成器函式。
yield
語句通常會暫停該函式並儲存區域性狀態,以便可以從中斷處繼續恢復。 生成器函式可以具有乙個或多個yield
語句。
生成器也是迭代器,但是什麼是迭代器? 在我們深入討論生成器之前,我認為了解迭代器是很重要的,因為它們構成了本次討論的組成部分。
python迭代器只是定義__iter__()
方法的類。 大多數python物件都是可迭代的,這意味著您可以遍歷物件中的每個元素。 python中可迭代的示例包括字串,列表,元組,字典和範圍。
讓我們考慮下面的示例,其中我們遍歷顏色列表:
colors= [「red」,」blue」,」yellow」]
def my_funct():
for color in colors:
print color
在幕後,for
語句將在列表物件上呼叫iter()
。 然後,該函式將返回乙個迭代器物件,該物件定義了__next__()
方法,該方法隨後將一次訪問每種顏色。 當沒有更多的顏色時,__next__
stopiteration
將引發乙個stopiteration
異常,該異常將反過來通知for
迴圈終止。
d =
for k,v in d.items():
print k, v
#result
# y 20
# x 10
# z 30
import csv
with open('file.csv', newline='') as file:
reader = csv.reader(file)
for row in reader:
yield row
my_string = 'generators'
for string in my_string:
print (string)
#result
# g# e
# n# e
# r# a
# t# o
# r# s
讓我們討論使用生成器而不是迭代器的一些好處:
易於實施
在python中構建迭代器將需要您使用__iter__()
和__next__()
方法實現乙個類,並注意可能導致stopiteration
錯誤的任何錯誤。
class reverse:
"""iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise stopiteration
self.index = self.index - 1
return self.data[self.index]
如您在上面看到的,實現非常冗長。 所有這些負擔由發電機自動處理。
更少的記憶體消耗
生成器有助於最大程度地減少記憶體消耗,尤其是在處理大型資料集時,因為生成器一次只會返回一項。
更好的效能和優化
發電機本質上是懶惰的。 這意味著它們僅在需要時才生成值。 與普通迭代器不同,在常規迭代器中,無論是否使用它們都會生成所有值,而生成器只會生成所需的值。 反過來,這將導致您的程式執行更快。
建立乙個生成器非常容易。 您需要做的就是編寫乙個普通函式,但是使用yield
語句而不是return
語句,如下所示。
def gen_function():
yield "python"
當return
語句完全終止乙個函式時,yield
只是暫停該函式,直到next()
方法再次呼叫它為止。
例如,下面的程式同時使用yield
和next()
語句。
def mygenerator(l):
total = 1
for n in l:
yield total
total += n
newgenerator = mygenerator([10,3])
print(next(newgenerator))
print(next(newgenerator))
讓我們看看生成器是如何工作的。 考慮下面的示例。
# generator_example.py
def mygenerator(l):
total = 0
for n in l:
total += n
yield total
newgenerator = mygenerator([10,20,30])
print(next(newgenerator))
print(next(newgenerator))
print(next(newgenerator))
在上面的函式中,我們定義了乙個名為mygenerator
的生成器,該生成器將列表l
作為引數。 然後,我們定義乙個變數total
並將其賦值為零。 另外,我們遍歷列表中的每個元素,然後將其新增到total變數中。
然後,我們例項化newgenerator
並在其上呼叫next()
方法。 這將執行**,直到產生total
的第乙個值(在這種情況下為0
。 然後,該函式將保留total變數的值,直到下次呼叫該函式為止。 與普通的return
語句(一次返回所有值)不同,生成器將從中斷的地方開始提取。
以下是其餘的後續值。
# generator_example.py
def mygenerator(l):
total = 0
for n in l:
yield total
total += n
newgenerator = mygenerator([10,20,30])
print(next(newgenerator))
print(next(newgenerator))
print(next(newgenerator))
# result
# 0# 10
# 30
如果嘗試在函式完成迴圈後呼叫該函式,則會收到stopiteration
錯誤。
next()
方法引發stopiteration
,以表明迭代器不再產生其他項。
0
1030
traceback (most recent call last):
file "python", line 15, in stopiterationnormal function
例子2
在這個例子中,我們展示了如何在乙個函式中使用多個yield語句。
# colors.py
def colors():
yield "red"
yield "blue"
yield "green"
next_color =colors()
print(next(next_color))
print(next(next_color))
print(next(next_color))
# result
# red
# blue
# green
普通函式在呼叫該函式時會返回所有值,而生成器會等待直到再次呼叫next()
方法。 呼叫next()
,顏色函式將從其停止處恢復。
生成器的記憶體使用效率更高,尤其是在處理非常大的列表或大物件時。 這是因為您可以使用yield來處理較小的位,而不是一次將所有資料都儲存在記憶體中。
此外,不要忘記檢視我們可以在envato market上**和進行研究的產品 ,也可以使用以下供稿隨時提出任何問題並提供寶貴的反饋意見。
此外,如果您感到困惑,在課程部分中會有一門關於python生成器的很好的課程。
翻譯自:
python 生成器作用 Python生成器
生成器介紹 在函式內部包含yield關鍵字,那麼該函式執行的結果是生成器,生成器就是迭代器。生成器的功能 把函式結果做成迭代器 以一種優雅的方式封裝好iter,next 提供了一種自己定義迭代器的方式。使用生成器建立乙個迭代器 def a print a yield 11 使用yield,執行後返回...
python生成器好處 Python生成器筆記
python中三大器有迭代器,生成器,裝飾器,本文主要講述生成器。主要從生成器的概念,本質,以及yield關鍵字的使用執行過程。本質 生成器是一類特殊的迭代器,使用了yield關鍵字的函式不再是函式,而是生成器。使用了yield的函式就是生成器 1.yield關鍵字有兩點作用 1.1 yield語句...
python生成器函式 Python 生成器函式
一 生成器 生成器指的是生成器物件,可由生成器表示式得到,也可使用 yield 關鍵字得到乙個生成器函式,呼叫這個函式得到乙個生成器物件 生成器物件,是乙個可迭代物件,是乙個迭代器 生成器物件,是延遲計算 惰性求值的 1.1 生成器函式 函式體重包含 yield 語句的函式,就是生成器函式,呼叫後返...