Python

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关键字

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
上一篇下一篇

猜你喜欢

热点阅读