首页 > 技术文章 > Python学习之==>迭代器

L-Test 2019-01-01 17:37 原文

一、概要

在了解Python的数据结构时,容器(container)、可迭代对象(iterable)、迭代器(iterator)、生成器(generator)、列表/集合/字典推导式(list,set,dict comprehension)众多概念参杂在一起,难免让人一头雾水,下面这幅图也许能让大家更清楚的理解他们之间的关系。

 

二、容器(container)

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用 in , not in 关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特列并不是所有的元素都放在内存)在Python中,常见的容器对象有:

  • list
  • dict
  • set
  • tuple
  • str

尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是可迭代对象赋予了容器这种能力,当然并不是所有的容器都是可迭代的。

三、可迭代对象(iterable)

一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。很多容器都是可迭代对象(比如:list、dict、tuple等),此外,像打开的文件,也是可迭代对象。但凡可以返回一个迭代器的对象都可成为可迭代对象。

这里x是一个list,是一个可迭代对象。我们知道,list、dict、set、tuple、str都是可迭代对象,通过iter()或__iter__(),就可以转化为一个迭代器。所以,我们可以说:一个具有iter方法的对象就可以称为可迭代对象。

四、迭代器(iterator)

上图中,y和z就是两个独立的迭代器,它是通过iter()方法从可迭代对象转化而来的。它是一个带状态的对象,该状态用于记录当前迭代所在的位置,以便下次迭代的时候取到正确的元素。它能在你调用 next() 方法的时候返回容器中的下一个值,任何实现了 __next__() 或next()方法的对象都是迭代器。迭代器有一种具体的迭代器类型,比如 list_iterator、set_iterator、tuple_iterator、str_iterator等 。

五、for循环的内部实现

在大多数情况下我们都不会用next()方法去可迭代对象中去取值,而是会用:for i in (iterable),如下图:

for循环内部做了3件事情:

  1. 调用iter()把可迭代对象转换成迭代器
  2. 不断的调用迭代器的next()方法
  3. 处理StopIteration异常,结束循环

六、isinstance

可以使用isinstance()判断一个对象是否是Iterator对象,如下:

 1 from collections import Iterator,Iterable
 2 l = [1,2,3,4,5]
 3 d = iter(l)
 4 print(isinstance(l,list))      # 判断是否是list
 5 print(isinstance(l,Iterable))  # 判断是否是可迭代对象
 6 print(isinstance(l,Iterator))  # 判断是否是迭代器
 7 print(isinstance(d,Iterator))  # 判断是否是迭代器
 8 # True
 9 # True
10 # False
11 # True

 

推荐阅读