Python 生成器


生成器


image

1. 什么是生成器

生成器是一個返回迭代器的函數,只能用於迭代操作,更簡單點理解生成器就是一個迭代器。

不同於一般的函數會一次性返回包括了所有數值的數組,生成器一次只能產生一個值,這樣消耗的內存數量將大大減小,而且允許調用函數可以很快的處理前幾個返回值。

2 創建生成器

生成器可以通過生成器表達式和生成器函數獲取到

生成器表達式

創建生成器對象和創建列表生成式特別像

# 創建列表生成式
>>> list_num = [x for x in range(10)]
>>> list_num
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 生成器
>>> glist_num = (x for x in range(10))   # 只需要把中括號換成小括號就成了生成器
>>> glist_num
<generator object <genexpr> at 0x7fc3d7375830>
>>> glist_num.__next__()
0
>>> glist_num.__next__()
1
>>> next(glist_num)
2
>>> next(glist_num)
3

# 生成器表達式內部的代碼只有在迭代取值的時候才會執行

使用next()和使用__next__()一樣

生成器函數

生成器函數指的是函數體中包含yield關鍵字的函數

定義生成器函數和定義普通函數一樣。

# 1 生成器函數
>>> def my_func():
        print("Hello")
        yield 
    
>>> my_func()
<generator object my_func at 0x7fc3d6c70e08>
>>> res = my_func()
>>> res
<generator object my_func at 0x7fc3d6c70e60>
>>> next(res)
Hello
>>> 
>>> next(res)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

# 生成器函數(yield有返回值)

def my_func():
    print("Hello")
    yield 1

res = my_func()

r = res.__next__()   # 會執行 print("Hello")

print(r)  # r為yield的返回值

# 執行結果:
Hello
1

# 生成器函數(yield多個返回值)
def my_func():
    print("Hello")
    yield 1,2

res = my_func()

r = res.__next__()

print(r)

# 執行結果:
Hello
(1, 2)

#函數中只有一個yield所以只能執行一次__next__()方法
def my_func():
    print("Hello")
    yield 1,2

res = my_func()

print(res.__next__())
print(res.__next__())  # 調用兩次就會報錯

#執行結果: 
Hello
(1, 2)
Traceback (most recent call last):
  File "b.py", line 8, in <module>
    print(res.__next__())
StopIteration

# 有多個yield
def my_func():
    print("Hello")
    yield 1,2		
    print("world")
    yield 'a','b' 

res = my_func()

print(res.__next__()) # 每執行一個__next__代碼往下運行到yield停止 返回后面的數據
print(res.__next__()) # 每執行一個__next__代碼往下運行到yield停止 返回后面的數據

注意:當函數體內含有yield關鍵字 那么在第一次調用函數的時候,並不會執行函數體代碼,而是將函數變成了生成器(迭代器).

每執行一個__next__代碼往下運行到yield停止 返回后面的數據.

yield不但能返回值,而且還能給它傳值

yield傳值

使用sendyield傳值

示例:

def my_define(name):
    print("%s is doing work" % name)
    while True:
        play  = yield
        print("%s is do %s" %(name, play))


res = my_define("Hans")

res.__next__()
res.__next__()

# 執行結果:
Hans is doing work
Hans is doing None

# 給yield傳值:
def my_define(name):
    print("%s is doing work" % name)
    while True:
        play  = yield
        print("%s is do %s" %(name, play))


res = my_define("Hans")

res.__next__()
res.__next__()
# 給yield傳兩個值:write和coding
res.send("write")
res.send("coding")

# 執行結果:
Hans is doing work
Hans is do None
Hans is do write
Hans is do coding

3 生成器練習

模擬range功能

# 代碼
def my_range(start, stop=None, step = 1):
    if not stop:
        stop = start
        start = 0

    while start < stop:
        yield start
        start += step

print("一個參數")
for i in my_range(3):
    print(i)
    
print("兩個參數")
for i in my_range(1,3):
    print(i)

print("三個參數")
for i in my_range(1, 10, 2):
    print(i)
# 執行結果:
一個參數
0
1
2
兩個參數
1
2
三個參數
1
3
5
7
9

求和(面試題)

# 代碼:
def add(n, i):
    return n + i

def test():
    for i in range(4):
        yield i
g = test()
for n in [1, 10]:
    g = (add(n, i) for i in g)
  
res = list(g)
print(res)

#從下面的結果中選擇一個:

#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
#C. res=[20,21,22,23]
#D. res=[21,22,23,24]


# 解析:
def add(n, i):
    return n + i
# 調用之前是函數 調用之后是生成器
def test():
    for i in range(4):
        yield i
g = test()  # 初始化生成器對象
for n in [1, 10]:
    g = (add(n, i) for i in g)
    """
    第一次for循環
        g = (add(n, i) for i in g)
    第二次for循環
        g = (add(10, i) for i in (add(10, i) for i in g))
    """
res = list(g)
print(res)

#執行結果為:[20,21,22,23], 答案選C
#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
#C. res=[20,21,22,23]
#D. res=[21,22,23,24]

4 yield和return的區別

yield

  1. 可以返回值(支持多個,並且組織成元組)
  2. 函數體代碼遇到yield不會結束而是阻塞
  3. yield可以將函數變成生成器 並且還支持外界傳值

return

  1. 可以返回值(支持多個並且組織成元組)
  2. 函數體代碼遇到return直接結束

5 生成器和迭代器總結

迭代器對象 生成器對象 我們都可以看成是"工廠",只有當我們所要數據的時候工廠才會加工出"數據"

主要目的就是節省空間

6. Python中內置函數

內置函數
abs() divmod() input() open() staticmethod()
all() enumerate() int() ord() str()
any() eval() isinstance() pow() sum()
basestring() execfile() issubclass() print() super()
bin() file() iter() property() tuple()
bool() filter() len() range() type()
bytearray() float() list() raw_input() unichr()
callable() format() locals() reduce() unicode()
chr() frozenset() long() reload() vars()
classmethod() getattr() map() repr() xrange()
cmp() globals() max() reverse() zip()
compile() hasattr() memoryview() round() import()
complex() hash() min() set()
delattr() help() next() setattr()
dict() hex() object() slice()
dir() id() oct() sorted() exec 內置表達式
內置函數
https://docs.python.org/zh-cn/3/library/functions.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM