Python的迭代器与生成器

for的本质

容器对象都可以直接用于for语句迭代

for element in [1, 2, 3]:
    print(element)
for element in (1, 2, 3):
    print(element)
for key in {'one':1, 'two':2}:
    print(key)
for char in "123":
    print(char)
for line in open("myfile.txt"):
    print(line, end='')

其背后是在python中被广泛使用的迭代器,for语句在容器对象上调用iter(), 得到一个迭代器对象,迭代器对象的方法__next__()每次调用访问容器中的一个元素,当没有额外的元素时,next()中StopIteration异常被抛出,for循环停止。

正如iter()调用容器对象的__iter__()一样,next()调用对象的__next__()。

迭代器与可迭代对象

iter()的调用返回拥有方法__next__()的迭代器对象,用于迭代数据。而定义了__iter__(),可作为参数用于iter()的对象则是可迭代对象,上述例子中的各种容器对象都是可迭代对象。

构造符合上述迭代协议的对象,即可直接用于for语句

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s

一个对象可以既是迭代器对象的同时又是可迭代对象。

生成器

生成器是一种简单,功能强大的创建迭代器的工具。生成器的定义和一般的函数一致,只不过在返回数据的地方不用return,而用yield语句。

每一次next()被调用,生成器都会恢复到之前的上下文继续执行。

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

>>>
>>> for char in reverse('golf'):
...     print(char)
...
f
l
o
g

生成器简洁的背后是__iter__()和__next__()被自动的创建,以及StopIteration被自动抛出。同时由于生成器的每次恢复执行,都能自动恢复之前的上下文,所以不再需要上述中基于类的迭代器版本中的实例变量self.index,和self.data.

生成器表达式

类似列表推导式,简单的生成器可以用更简洁的生成器表达式的方式创建,只需把大括号改为小括号。生成器表达式常用在生成器直接被作为外围函数参数使用的情景。

>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']
>>> sum(i*i for i in range(10)) # sum of squares
285
>>> unique_words = set(word  for line in page  for word in line.split())
>>> valedictorian = max((student.gpa, student.name) for student in graduates)

生成器表达式比等价的列表推导式对内存更加友好,但是生成器表达式无完整定义的生成器表达能力强。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值