Python基础语法:生成器 generator(yield)
·
一、简介
根据指定的规则循环生成数据,当条件不成立时则生成数据结束。数据不是一次性全部生成出来,而是使用一个,再生成一个,好处是可以节约大量的内存。就像设计模式中的懒汉式。适合处理大数据或流数。
生成器是一种特殊的迭代器,使用 yield 关键字而不是 return 来返回值。它可以在迭代过程中动态生成值,而不是一次性生成所有值。
创建生成器的方式: ① 生成器推导式 ② yield 关键字
- 生成器函数使用关键字
yield来返回值。yield = return + next() - 调用一个生成器函数,返回的是一个迭代器对象, 而不会执行函数体。
- 生成器函数同时具有迭代器的特性:通过
next(gen)方法来获取下一个值。 - 每次执行next(gen)函数时遇到yield关键字就会
return, 并且在下一次执行next(gen)时会从yield关键字的下一行代码开始执行。
二、生成器推导式
元组没有推导式,元组的推导式是
gen = (i for i in range(1, 11) if i % 2 == 0)
# <class 'generator'>
print(type(gen))
print(next(gen)) # 2
print(next(gen)) # 4
"""
for i=6
for i=8
for i=10
"""
for i in gen:
print(f"for i={i}")
generator 比 list 占用内存更小。
import sys
my_list =[i for i in range(10000000)]
my_gen =(i for i in range(10000000))
print(type(my_list),type(my_gen))
# getsizeof:查看变量占用的内存大小
print(sys.getsizeof(my_list)) # 89095160
print(sys.getsizeof(my_gen)) # 200
三、yield 关键字
示例1
循环list
def get_list():
my_list = []
for i in range(1, 11):
my_list.append(i)
return my_list
for i in get_list():
print(i)
循环生成器
def get_gen():
for i in range(1, 11):
yield i
for i in get_gen():
print(i)
示例2
def generate(n):
print("初始化代码,只执行一次...")
i = 1
while True:
print(f"循环体={i}")
if i > n:
break
yield i
i += 1
print(f"yield i={i}")
print("*" * 10)
gen = generate(3)
print("*" * 10)
print("result=", next(gen))
print("*" * 10)
for x in generate(5):
print(x)
send(value) 函数可以将参数值传递到生成器内来引用。
- 调用send(value)方法时第一次必须传None参数,或者在调用send(value)方法前调用next(gen)
- gen.send(None)==next(gen)
def generate():
print("初始化代码,只执行一次...")
i = 1
while True:
print(f"循环体={i}")
if i > 5:
raise StopIteration
# send_value 并不影响i的值
send_value = yield i
i += 1
print(f"yield i={i} send_value={send_value}")
gen = generate()
# 初始化代码,只执行一次...
# 循环体=1
# result= 1
print("result=", next(gen))
# yield i=2 send_value=4
# 循环体=2
# result= 2
print("result=", gen.send(4))
# yield i=3 send_value=None
# 循环体=3
# result= 3
print("result=", next(gen))
四、应用场景
def fibonacci():
"""无限斐波那契数列生成器"""
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
print(next(fib)) # 0
print(next(fib)) # 1
print(next(fib)) # 1
print(next(fib)) # 2
print(next(fib)) # 3
import math
def get_page_data(page_size):
"""
读取文件中的歌词,一次读取page_size条
:param page_size: 每页数量
:return: 每页歌词条数
"""
#1 读歌词
with open('./data/bye','r') as file :
lines = file.readlines()
#2 总条数
total_num = len(lines)
#3 总页数
total_page = math.ceil(total_num / page_size)
print(f"total_num={total_num}, page_size={page_size}, total_page={total_page}")
#4 遍历每页
for page_no in range(total_page):
yield lines[page_no * page_size: page_no * page_size + page_size]
data_gen = get_page_data(5)
print(type(data_gen)) # <class 'generator'>
for page_data in data_gen:
print(page_data)


更多推荐
所有评论(0)