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

发布时间 2023-06-05 18:11:58作者: 毓见

生成器

生成器的背景:


"""
	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关键字后面的数据用逗号隔开,有多个的时候,会以元组的形式返回

自定义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('臭豆腐')
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