Python中的Iterator和Generator

Iterator

Iterator 是Python 中用于 for in 的一种类型,如果要将对象实现为Iterator,该对象需要实现两个魔法方法__iter____next__

__iter__

该方法在Iterator 初始化的时候被调用,用于返回一个可以迭代的对象,该对象需要实现__next__方法。

__next__

该方法每次应该返回迭代的下一个值,并且在迭代结束时,抛出异常 StopIteration 表示迭代结束。

示例

如下的Fib类被实例化后,可以用于 for in 中迭代斐波纳切数列。

class Fib:
    def __init__(self, lim: int = 100):
        self.pre_num = 1
        self.cur_num = 1
        self.lim = lim

    def __iter__(self):
        return self

    def __next__(self):
        self.pre_num, self.cur_num = self.cur_num, self.cur_num + self.pre_num
        if self.pre_num > self.lim:
            raise StopIteration
        return self.pre_num


fib = Fib()
for each in fib:
    print(each)¡

Generator

Generator function

函数体内包含有 yield 关键字的函数将被视为 generator function,当它想要返回一个结果时,使用 yield 而不是 return。此时,函数将会被Python Frame挂起,并将返回前的状态保存下来。等下一次该函数再被调用时,Frame将恢复挂起的状态并继续执行。示例如下:

def fib(limit):
    a, b = 0, 1
    while a < limit:
        yield a
        a, b = b, a + b

Gernerator object

当有如下执行语句时,generator function 的返回值不是结果,而是一个generator 对象。

# "fib" implementation refers to above one.
f = fib(100)
for each in f:
    print(each)

该对象和 Iterator 类似,可以用 for in 语句来进行迭代,结束也会抛出异常 StopIteration表示迭代终止。

Generator expression

使用Generator 表达式可以生成一个匿名的Generator function,语法就是将列表推导式的中括号变为小括号。如下:

# Output: <generator object <genexpr> at 0x0000000002EBDAF8>
(x**2 for x in my_list)

不像列表推导式会直接返回一个列表,生成器表达式仍然遵循生成器的规则,每次 next 返回一个结果。该表达式还可以作为函数的传入参数,此时可以省去表达式两端的小括号,如下:

# Output: 146
sum(x**2 for x in my_list)

Generator优势

实现简洁

相较于Iterator,生成器的__iter__, __next__方法和 StopIteration 异常都由Python隐式地生成。

内存高效

普通的函数在返回一个序列前,需要将完整的序列保存到内存中。如果一个序列包含了大量的items,将会造成严重的内存占用。而生成器每次只产生一个item。

表示无限序列

无限的序列无法用容器存放,但可以用Generator来表示。

流水线

通过流水线可以获得更高的可读性和效率,例如:


with open('sells.log') as file:

    pizza_col = (line[3] for line in file)

    per_hour = (int(x) for x in pizza_col if x != 'N/A')

    print("Total pizzas sold = ",sum(per_hour))

Reference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值