python基础:生成器

生成器的本质就是迭代器。
生成器包括两种:生成器函数和生成器表达式
1.生成器函数
一个包含yield关键字的函数就是一个生成器函数。并且yield不能和return共用,并且yield只能用在函数内。

(1).生成器函数执行之后会得到一个生成器作为返回值,并不会执行函数体。
(2).执行了__next__()方法之后才会执行函数体,并且获得返回值。
(3).next()内置方法,内部调用生成器函数的__next__()方法。
(3).yield和return相同的是可以返回值,但是不同的是yield 不会结束函数

练习1:创建一个生成器,并且调用

def generator():
    print('xxxx')
    yield
    print('zzzz')
    yield

ret=generator()
print(ret)      # 返回一个生成器对象,也就是一个迭代器,必须使用__next__方法才能执行函数体
ret.__next__()  # 调用__next__方法执行函数体,遇到yield停止
# 也可以写成next(ret)的方式
next(ret)
# ret.__next__()  # 执行前面,没有遇到yield然后报错
# next(ret)       # 执行前面,没有遇到yield然后报错

运行结果:

<generator object generator at 0x0000000001E25830>
xxxx
zzzz

练习3:创建生成器,定义多个yield 值

def generator():
    print('---->')
    yield 1

    print('---->')
    yield 2

g = generator()
ret = next(g)  # ---->
print(ret)  # 1
ret2 = g.__next__()  # ---->
print(ret2)  # 2

运行结果:

---->
1
---->
2

练习4:创建生成器,生成200万桶康师傅方便面

def ksf():
    for i in range(1, 2000000):
        yield '正在生成第{}桶方便面'.format(i)


g=ksf()
# ret=next(g)
# print(ret)  # 此种方法只会执行一次
import time
for fbm in g:
    time.sleep(1)
    print(fbm)

运行结果:

正在生成第1桶方便面
正在生成第2桶方便面
正在生成第3桶方便面
正在生成第4桶方便面
正在生成第5桶方便面
......

2.send()方法
send 获取下一个值的效果和next()基本一致,只是在获取下一个值的时候,给上一yield的位置传递一个数据
使用send的注意事项
(1).第一次使用生成器的时候 是用next获取下一个值
(2).最后一个yield不能接受外部的值
使用send()方法给yield传递参数

def generator():
    print('aa')
    content=yield 1
    print(content)
    print('--->')
    yield 2

g=generator()
ret=next(g)    # aa
print(ret)    # 1
g.send('hello')   # 将hello传给content
# g.send('zz')  # 报错,下面没有yield来停止了

运行结果;

aa
1
hello
--->

练习2:计算移动平均值

def fun_avg():
    count=1
    avg=0
    total=0
    while True:
        get_num=yield avg
        total+=get_num
        avg=total / count
        count+=1

g=fun_avg()
print(next(g))
print(g.send(10))
print(g.send(20))
print(g.send(30))

运行结果:

0
10.0
15.0
20.0

3.yield form
yield from 循环遍历容器类型

练习1:使用for循环取出g1生成器中所有的值。
普通方法:

def g1():
for i in range(3):
yield i
for j in ‘ab’:
yield j

a=g1()
print(a.next())
print(a.next())
print(a.next())
print(a.next())
print(a.next())
运行结果;

0
1
2
a
b

此种方法较为繁琐,需要从返回的迭代器中一个一个的取

使用yield form方法

def g1():
    yield from range(3)
    yield from 'ab'
a=g1()
for gg in g1():
    print(gg)

运行结果;

0
1
2
a
b

4.生成器表达式
格式:将列表解析式[] 改成 () 即可。
练习1:使用生成器表达式,进行数数。

g=(i for i in range(10))
print(g)   # 返回生成器对象
for i in g:
    print(i)

运行结果:

<generator object <genexpr> at 0x0000000002175830>
0
1
2
3
4
5
6
7
8
9

使用类型转换形式遍历迭代器

def demo():
    for i in range(4):
        yield i

g=demo()
# 函数底层会默认调用g的__next__()方法
print(list(g))  # [0, 1, 2, 3]

运行结果:

[0, 1, 2, 3]

5.生成器作用
可以实现多任务(协程–>模拟并发)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值