Python进阶09 迭代器

一、迭代器

我们已经知道,集合数据类型(如list、tuple、dict、set、str等)和generator都可以直接作用于for循环。这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

1、可以使用isinstance()判断一个对象是否是Iterable对象:

>>> from collections.abc import Iterable
>>> isinstance([1, 2, 3], Iterable)
True
>>> isinstance({1, 2, 3}, Iterable)
True
>>> isinstance('ABC', Iterable)
True
>>> isinstance((x for x in range(5)), Iterable)
True
>>> isinstance(100, Iterable)
False

2、可以使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections.abc import Iterator
>>> isinstance((x for x in range(5)), Iterator)
True
>>> isinstance([1, 2, 3], Iterator)
False
>>> isinstance({1, 2, 3}, Iterator)
False
>>> isinstance('ABC', Iterator)
False

Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

二、iter()函数

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([1, 2, 3]), Iterator)
True
>>> isinstance(iter('ABC'), Iterator)
True
>>> isinstance(iter({1, 2, 3}), Iterator)
True

三、迭代器协议

实现了方法__iter__的对象是可迭代的,而实现了方法__next__的对象是迭代器。

class Fibs:
    def __init__(self):
        self.a = 0
        self.b = 1

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        return self.a

    def __iter__(self):
        return self
fibs = Fibs()

for f in fibs:
    print(f)
    if f > 10:
        break

结果:
1
1
2
3
5
8
13

四、从迭代器创建序列

除了对迭代器和可迭代对象进行迭代之外,还可将它们转换为序列。

一个这样的例子是使用构造函数list显示地将迭代器转换为列表。

class TestIterator:
    value = 0

    def __next__(self):
        self.value += 1
        if self.value > 10:
            raise StopIteration

        return self.value

    def __iter__(self):
        return self

ti = TestIterator()
print(list(ti))

结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

参考文章:

https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640

猜你喜欢

转载自www.cnblogs.com/mazhiyong/p/12566362.html
今日推荐