python基础day18 生成器相关

生成器(迭代器的一种)

生成器的背景

  我们现在定义的列表,内部元素都比较少,占用的内存也是比较少的,几乎可以忽略。但是,如果定义一个列表,内部有100W个元素,可是我们只用到了前面或后面的几个元素,其他元素很少用,如果我们把这100W个元素都写在列表里,每次使用的时候都打印了,就会出现占据大量内存的情况。针对这个问题可以使用生成器进行优化。

  如果不用这些数据,再打印的时候给一个对象,不给具体的数据,什么时候使用这些数据,再给你。

生成器解决的问题是什么?

就是节省内存空间。

range(10)在python3中就是一个生成器,节省了内存空间。

如何使用

复制代码
def index():
    print('from index')
    yield 123,234,345
"""函数里面只要出现了yield关键字,那么,该函数就有普通的函数变成了生成器,就不在执行该函数了"""
res=index()
# print(res)  # <generator object index at 0x000001F5008287B0>
# 要想使用生成器只需要使用next取值即可
# 我们使用next取值,每next一次,代码走到第一个 yield 处停止。

print(res.__next__())  # None (123, 234, 345)

# print(res.__next__())  # None  再次执行next,会从上一次yield的位置处往下继续走,走到遇到第二个yield停止

"""如果你打印next的结果,就会返回yield关键字后面的数据"""
# 当yield关键字后面的数据用逗号隔开,有多个的时候,会以元组的形式返回
复制代码

自定义range功能

复制代码
range(10)

range(1, 10)

range(1, 10, 2)
# range函数不能用了,我让你写一个跟range函数一样的功能? 使用生成器来做:yield

# range()

# None:假 not None
def my_range(start, stop=None, step=1):
    # 判断传了一个参数还是两个参数
    if not stop:
        stop = start # stop=10
        start = 0 # start =0

    while start < stop:
        yield start
        start+=step


res=my_range(1, 10)
# print(res.__next__())
# print(res.__next__())

# for i in my_range(10, 100, 2): # __next__
#     print(i)

for i in my_range(10): # __next__
    print(i)
复制代码

yield关键字的传参问题

复制代码
def eat(name):
    print('%s正在干饭' % name)
    while True:
        food = yield
        print('%s正在吃%s' % (name, food))

# 函数里面只要有yield关键字,就不会执行函数,变成了生成器
res=eat('kevin')
# res.__next__()
res.__next__()

"""
1. 把参数传给了yield
2. 执行了__next__取值
"""
res.send('馒头')
res.send('馒头1')
res.send('馒头2')
复制代码

return和yield的对比

return
    1. 函数遇到return直接终止运行
    2. return也可以返回多个值
yield
    1. 函数遇到yield代码不会立即终止运行,而是会''停住''
    2. yield 也可以返回多个值,以元组的形式返回
    3. yield 可以把函数编程生成器,而且还支持传参

生成器表达式

复制代码
# 列表生成式
res = [i for in range(10)]

res1 = (i for in range(10))
print(res1)  # <generator object <genexpr> at 0x0000018083EA3A50>

print(res1.__next__())
print(res1.__next__())
print(res1.__next__())

"""生成器表达式如果你不去__next__,是不会给你造出来数据的"""

迭代器和生成器什么关系:

    '''生成器他是特殊的一种迭代器'''
    
"""
    迭代器、生成器我们都可以把它们看成是"工厂"
    你什么时候要数据我们就设么时候给你生产
    上述这样做的原因:
        节省内存空间
"""
复制代码

例题

复制代码
# 求和
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]
复制代码

常用内置函数

 

posted @   吼尼尼痛  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示