生成器
使用场景:
在使用列表时,很多时候我们不会一下子使用数据,通常都是一个一个使用;当数据量较大的时候,定义一个列表会是程序内存占用突然增大,为了解决此类问题,python中引入了生成器。
关于列表生成式
# 列表生成式:可以快速方便地生成列表
print([i for i in range(1, 11)])
print([i for i in 'abcdefg'])
print([i*2 for i in range(1, 11)])
print([i*i for i in range(1, 11)])
print([str(i) for i in range(1, 11)])
print([i for i in range(1, 11) if i % 2 ])
# 生成的列表可以与遍历的内容没有一毛钱关系
print([10 for i in range(1, 11)])
如果列表元素可以按照某种算法推算出来,那我们可以在循环的过程中不断推算出后续的元素 这样就不必创建完整的list 这样就引出了生成器(generator
)
生成方式一:
将列表生成式的[]改为()即可
# 列表生成式
# lt = [i for i in range(10)]
# print(lt) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lt = (i for i in range(3))
print(lt) #<generator object <genexpr> at 0x000001A4A5915A98>
# 可以转换为列表
# print(list(lt)) #[0, 1, 2]
# 可以进行遍历
for i in lt:
print(i)
0
1
2
# 可以一个一个提取,当提取结束后再次提取会报StopIteration错
# print(next(lt))
# print(next(lt))
# print(next(lt))
# print(next(lt)) #StopIteration
生成方式二: 在函数中使用yield关键字
'''
# 当数据量特别大的时候,占用内存会突然增大
def test(n):
lt = []
for i in range(1, n+1):
lt.append(i)
return lt
print(test(10))
'''
print('-----------------------------------------------')
def test(n):
for i in range(1, n + 1):
# 执行到此处,函数会返回yield后的内容,然后会停止在这里
yield i
t = test(3)
print(t) #[1,2,3]
# 可以一个一个提取
print(next(t))
print(next(t))
print(next(t))
# 可以遍历
# for i in t:
# print(i)
# 可以转换为列表
# print(list(t))
在函数中加入yield
以后 test
不在是一个普通的函数 而是一个generator
在执行过程中,遇到yield
返回yield
后的内容,就停止执行 等待下次next()
的执行
当然 我们将函数test()
变成一个generato
后 我们就不在使用next
进行取出值, 我们通过循环遍历取值 可以一次性取出所有的值
在用用for
循环调用generator
时,发现拿不到generato
r的return
语句的返回值。如果想要拿到返回值,必须捕获StopIteration
错误,返回值包含在StopIteration
的value
中
def test(n):
for i in range(1, n + 1):
yield i
t = test(3)
while 1:
try:
x=next(t)
print('x:',x)
except StopIteration as e:
print('StopIteration的原因为:',e.value)
break
#x: 1
#x: 2
#x: 3
#StopIteration的原因为: None