深入浅出 Python Iterators 迭代器

原文

iterator protocol

iterator object必须实现两个method:
__iter()____next()__

注意: Python 3 中使用__iter__()__next__();Python 2 中使用__iter__()next()

iterable

iterable是个名词
list, tuple, dict都是iterable
可以用for x in yyy形式的yyy都是一个iterable

iterator、 iter()、 next()

如果一个对象yyy是iterable,那么可以用a = iter(yyy)获得一个iterator a

也可以用yyy.__iter__()

再用next(a)手动进行一次迭代/iterate

也可以用a.__next__()

当一个iterator已经迭代到头了,下一次next()会报StopIteration错误
下面是一个例子

# define a list
my_list = [4, 7, 0, 3]

# get an iterator using iter()
my_iter = iter(my_list)

## iterate through it using next() 

#prints 4
print(next(my_iter))

#prints 7
print(next(my_iter))

## next(obj) is same as obj.__next__()

#prints 0
print(my_iter.__next__())

#prints 3
print(my_iter.__next__())

## This will raise error, no items left
next(my_iter)

for loop的实现原理

for element in iterable:
    # do something with element

对应的实现代码是:

# create an iterator object from that iterable
iter_obj = iter(iterable)

# infinite loop
while True:
    try:
        # get the next item
        element = next(iter_obj)
        # do something with element
    except StopIteration:
        # if StopIteration is raised, break from loop
        break

构建自己的Iterator

对于一个类,只要实现__iter__()__next__()方法即成为一个iterator
__iter__() method返回iterator对象本身,同时也可以做一些初始化工作
__next__() method返回一系列迭代值,最后通过raise StopIteration错误来结束迭代
下面的例子每次迭代返回一个2幂次方,幂指数从0一直到用户给定的值

class PowTwo:
    """Class to implement an iterator
    of powers of two"""

    def __init__(self, max = 0):
        self.max = max

    def __iter__(self):
        self.n = 0
        return self

    def __next__(self):
        if self.n <= self.max:
            result = 2 ** self.n
            self.n += 1
            return result
        else:
            raise StopIteration

那么运行结果为:

>>> for i in PowTwo(5):
...     print(i)
...     
1
2
4
8
16
32

Infinite Iterators

迭代器可以是无限迭代的,例如依次返回所有的奇数。
不过使用时必须谨慎处理,加上适当的终止条件。
Python built-in 函数iter()可以有两个参数
一参是一个callable object (如function)
二参是一个sentinel value (终止条件/ terminating condition)。
迭代器会调用这个function直到返回值等于sentinel value。
例如,

>>> int()
0

>>> inf = iter(int,1)
>>> next(inf)
0
>>> next(inf)
0

iter(int, 1)返回了一个迭代器,这个迭代器遇到1时终止迭代。

注意:遇到1直接raise StopIteration,而不是下次迭代raise StopIteration

int()(int的构造函数)永远都返回0
因此这个迭永远不会停止,即成为一个infinite iterator.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值