Python3.7之生成器
一、生成器概念
Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。主要有两种结构可以延迟结果创建。生成器函数和生成器表达式。
1.生成器函数
和其他函数编写方式相同,但是使用yield语句一次返回一个结果,在每个结果之间挂起当前状态,下次调用的时候会从当前状态继续。
def count(n):
yield n**2
for i in range(5):
print(count(i).__next__())
'''
0
1
4
9
16
'''
2.生成器表达式
类似于列表解析,不同的是它返回的是一个可迭代对象而不是一个列表。
a = (m**2 for m in range(5))
print(type(a))
# <class 'generator'>
注意:生成器是一个对象,我们用的是()而不是[]。用[]就等于创建一个列表。
任何使用了yield的函数就是生成器,生成器就是一个返回迭代器的函数,或者说生成器就是一个迭代器。
二、总结yield
实现斐波那契数列:
def feibo():
a = 0
b = 1
while True:
yield b # 先返回再暂停
a, b = b, a + b
f = feibo()
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
'''
1
1
2
3
5
8
13
'''
1.和return相似,返回值。
2.暂停迭代,直到调用下一个next()方法。先返回再暂停。
3.调用的时候返回生成器对象。
假如yield后面紧接着一个数据,就会把数据返回,作为next()函数或者for ...in...迭代出的下一个值。
三、send()
yield还能接收值,用send方法传入。
我们可以通过send()方法,向生成器内部传递参数。
next(g)相当于send(None)
def test():
i = 1
while i < 5:
temp = yield i**2
print(temp)
i += 1
t = test()
# 第一次运行只能使用next或者send(None)
print(t.__next__())
# send的作用相当于使生成器继续运行,并且传递的参数为yield的返回值(程序中即temp的值)
print(t.send("Hello World"))
print(t.__next__())
# 相当于send(None) 此时temp = None
'''
1
Hello World
4
None
9
'''
yield = a,会返回a。
b = yield,会把yield接收的值赋值给b。
def count(n):
x = 0
while x < n:
value = yield x
if value is not None:
print('Received value: %s' % value)
x += 1
x = count(5)
print(next(x))
print(x.send('hello'))
print(next(x))
'''
0
Received value: hello
1
2
'''
def h():
print("Wen Chuan")
m = yield 5
print(m)
d = yield 12
c = h()
print(next(c))
print(c.send("."))
'''
Wen Chuan
5
.
12
'''