python 实现生成器的几种方式
2020-04-14 本文已影响0人
eeert2
一、通过列表生成器来实现
和列表生成式使用相似,将两边的[]
改成()
即可创建生成器
from typing import List
def odd_nums(nums: List[int]):
"""筛选列表中的奇数并返回一个生成式"""
return (num for num in nums if num % 2 == 1)
使用时直接对生成器进行遍历即可:
if __name__ == '__main__':
for i in odd_nums([1, 2, 3, 4, 5, 6, 7, 8, 9]):
print(i)
二、使用yield
关键字
- 在函数中使用
yield
- 在函数中使用
def odd_nums(target=100):
"""从 0 到指定数字直接的所以奇数"""
value = 0
while value < target:
if value % 2 == 1:
yield value
value += 1
三、在类中使用生成器
生成器和普通的可迭代对象最大的不同就是,生成器只能使用一次
。
如果我们想要重复使用生成器,就要考虑在类中使用生成器
if __name__ == '__main__':
for i in odd_nums(): # 只有第一次会有结果
print(i)
for j in odd_nums():
print(j)
就像实现了__call__
可以直接在对象上执行调用一样,实现__iter__
后可以直接在对象上执行迭代,且不限迭代的次数。
class OddNum:
def __init__(self, target=100):
self.target = target
def __iter__(self):
value = 0
while value < self.target:
if value % 2 == 1:
yield value
value += 1
使用类生成器:
if __name__ == '__main__':
oddnum_gene = OddNum()
for value in oddnum_gene:
print(value)
四、总结
使用生成器最大的作用是可以节省内存,针对不同的场景,我们可以采用不同的数据结构
设计方式。
如果只是简单的遍历一次,那边使用列表生成器
或函数生成器
即可。
如果对数据有复杂的操作,或者需要多次迭代遍历,那就要考虑在使用在类
中实现生成器,这样可以帮助我们更好的扩展数据结构
。
例如我们需要通过下标访问数据内容,这通过单纯的生成器是无法实现的,但是使用类生成器
可以解决这个问题。
class OddNum:
...
def __getitem__(self, index):
for i, value in enumerate(self):
if i == index:
return value
按照下标访问生成器:
if __name__ == '__main__':
oddnum_gene = OddNum()
print(oddnum_gene[4]) # 9