彩虹然

rainbow-ran

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
'''
posted @ 2020-01-16 16:20  彩虹然  阅读(644)  评论(0编辑  收藏  举报