python生成器之关键字yield、自定义range功能、其他常见的内置函数

生成器

生成器的背景:


"""
	l = [1, 2, 3]
	我们现在定义的列表,内部元素都比较少,占用的内存也是比较少的,我们几乎可以忽略,
但是,如果我现在让你定义一个列表,里面存放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关键字后面的数据用逗号隔开,有多个的时候,会以元组的形式返回

生成器的使用场景


1. 节省内存
2. 不确定数据大小
3. 流式处理数据
4. 无限的数据

自定义range功能

'''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)

for循环底层原理:
    for 变量名 in 可迭代对象:
        循环体代码

yield关键字的传参问题

什么是yield?


yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性,value和done,分别代表返回值和是否完成。

yield无法单独工作,需要配合generator(生成器)的其他函数,如next,懒汉式操作,展现强大的主动控制特性。

如何传参?

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('臭豆腐')
res.send('螺蛳粉')

return和yield的对比

return
	1. 函数遇到return直接终止运行
    2. return也可以返回多个值

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

生成器表达式

列表生成式
res = [i for i in range(10)]

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

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

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

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

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

"""

  • 生成器表达式 列表解析式
    按需计算 (或称惰性求值延迟计算), 即需要的时候才计算值,可以简单的理解为,每次向生成器对象中要一个元素,这个生成器对象 才会返回一个元素立即返回值
    返回生成器,生成器也是迭代器, 可以迭代返回的是可迭代对象:列表
    返回的生成器从头到尾全都取完一遍值之后, 不能再回头取值了从头到尾全都取完一遍值之后,可以从头重新取值
  • ------------------------------------------------------------------------------------------------------

    常用内置函数

    具体使用方法请访问网址:https://www.yuque.com/liyangqit/lb35ya/cddzw1ugdvl8mut9

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