生成器函数学习

生成器:

生成器本身就是迭代器

创建生成器的两种方案:

1.生成器函数

2.生成器表达式

生成器函数:关键字yield

这里先来

def func():
    print(123)
    return 456

ret = func()  # 执行func()函数,然后把return的值给ret,打印:123
print(ret)  # 打印return返回值:456

生成器函数(生成器本身是可迭代的):

def func():
    print(123)
    yield 456 # 3.当函数中有yield,这个函数就是一个生成器函数,yield也有返回的意思

gen = func()  # 1.这里什么都没有输出,因为这里只是创建了一个生成器函数
print(gen)  # 2.打印:<generator object func at 0x019DBDF0> ,表示生成器在内存的地址
ret= gen.__next__() # 打印:123,next能让生成器执行到下一个yield,yield也有返回的意思,返回给next,得到一个返回值,我们赋值给ret
print(ret)  # 这里打印yield返回的456


>>>
<generator object func at 0x034EBDF0>
123
456

一个函数有多个yield:

def func():
    print(1111)
    yield '第一个yield'
    print(2222)
    yield '第二个yield'
    print(3333)
    yield '第三个yield'
    print('下面没有yield了')

gen = func() # 这里创建了个生成器,没有执行
r1 = gen.__next__()  # 输出:111
print(r1)            # 输出:第一个yield

r2 = gen.__next__()  # 输出:2222
print(r2)            # 输出:第二个yield

r3 = gen.__next__()  # 输出:3333
print(r3)            # 输出:第三个yield

r4 = gen.__next__()  # 输出:下面没有yield了,然后报错:StopIteration,说不能迭代了(不能往下走了)



>>>
Traceback (most recent call last):
  File "D:/pythonPLianxi1/python/20220221.py", line 20, in <module>
    r4 = gen.__next__()
StopIteration
1111
第一个yield
2222
第二个yield
3333
第三个yield
下面没有yield了

Process finished with exit code 1

生成器总结:

        1.里面有yield

        2.生成器函数在执行的时候,实际上是创建一个生成器出来,不是执行生成器

        3.必须使用__next__()来执行一段代码,会自动执行到下一个yield结束

        4.yield也是返回的意思,可以让一个函数分段执行

        5.当后面没有yield之后,再次__next__会报错StopIteration

生成器本身是非常省内存的

来个不省内存的

 # 买10000件衣服
def order():
    l = []
    for i in range(100000):  # 会比较耗资源
        l.append(f'衣服{i}')
    return l  # 列表占内存 会感觉到电脑有点卡了,pycharm内存占用了1.5G

ls = order()
print(ls) # 输出:...'衣服99998', '衣服99999']

用yield执行:

yield是把代码放到内存中执行,要的时候再调用会从上次执行的下一行开始执行,通过分批执行能节省内存空间

# 生成器来做--分批拿衣服(什么时候要,什么时候拿,比较智能,省内存)
# 因为生成器在内存存储了这段代码 ,要用的时候拿出来调用一下
def order():
    l= []
    for i in range(10000):
        l.append(f'衣服{i}')
        if len(l) == 50:  # 如果长度为50则返回
            yield l
            l = [] # 下次执行的之后清空列表,在上一行返回yield的时候代码停在那里,下次执行从这行开始

g = order()
l2= g.__next__()
print(l2)
# ['衣服0', '衣服1', '衣服........., '衣服47', '衣服48', '衣服49']

l3 = g.__next__()
print(l3)
# ['衣服50',......., '衣服97', '衣服98', '衣服99']

生成器本身也是迭代器:

        1.省内存

        2.惰性机制:找她要衣服才给我,不然不执行

        3.只能往下执行,不能往回走

生成器的send:一般用不太到,了解下,send是要给yield进行赋值的

'''
__next__和send
相同点:
1.可以执行到下一个yield

不同点:
send:给上一个yield对应变量赋值

'''
def func():
    print(111)
    a = yield 'aaa'
    print(222,a)
    b = yield 'bbb'
    print(333,b)
    yield 'ccc'


g = func()
r1 = g.__next__()  # 第一次执行必须用next,因为send是给上一个yield对应变量赋值,前面没有yield
print(r1)
r2 = g.send('这个嗯')
print(r2)

r3 = g.send('这里是哪里')
print(r3)


>>
111
aaa
222 这个嗯
bbb
333 这里是哪里
ccc

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值