首页 > 编程笔记

Python迭代器的用法

我们在前面使用过语句“for x in列表对象”,这就表示列表对象是可迭代的(Iterable)。那么如何判断某个对象是否可迭代呢?答案是可以使用collections.Iterable类来判断。

如下面的代码所示,列表是可迭代的,整数是不可迭代的,字符串是可迭代的。
>>> from collections import Iterable   # 引入Iterable类
>>> isinstance([], Iterable)                   # 列表是可迭代的
True
>>> isinstance(12, Iterable)                   # 整数是不可迭代的
False
>>> isinstance("12", Iterable)                 # 字符串是可迭代的
True

另外一个概念是迭代器(Iterator)。它可以作为内置函数 next() 的参数,每次按照一定顺序得到其中一个元素。但比较有趣的是,列表不是迭代器。同样可以用 collections.Iterator 类来判断某个对象是否是迭代器。

如下面的代码所示,列表和字符串都不是迭代器:
>>> from collections import Iterator   # 引入Iterator类
>>> isinstance([], Iterator)                   # 列表不是迭代器
False
>>> isinstance("abc", Iterator)                # 字符串也不是迭代器
False
那么列表是否可以作为 next() 的参数呢?答案是不可以。例如下面的代码:
>>> a = [1, 2, 3]                        # 创建列表对象a
>>> next(a)                              # 使用内置的next()接口函数,发生错误
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator
这比较容易理解,因为我们没有指定当前位置,但可以使用另外一个内置函数 iter() 来将其转换成 Iterator。下面的代码演示了这种用法:
>>> from collections import Iterable   # 引入Iterable和Iterator类
>>> from collections import Iterator
>>> a = [1, 2, 3]                      # 创建列表对象a
>>> isinstance(a, Iterable)            # 列表对象是可迭代的
True
>>> isinstance(a, Iterator)            # 列表对象不是迭代器
False
>>> it_a = iter(a)                     # 从列表对象得到迭代器it_a
>>> isinstance(it_a, Iterable)         # it_a是可迭代的,也是迭代器
True
>>> isinstance(it_a, Iterator)
True
>>> type(it_a)                         # it_a是列表型迭代器
<type 'listiterator'>
>>> next(it_a)                         # 得到一个数据
1
>>> it_a.next()                        # 使用另外一种方式得到一个数据
2
>>> next(it_a)
3
>>> next(it_a)                         # 没有数据了,抛出异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
迭代器的一个特点是它只能使用一次,从头部走到尾部。如果希望再次走一遍,只能创建一个新的迭代器。

优秀文章