在学习Python的数据结构时,列表/集合/字典推导式(list set dict comprehension)、可迭代对象(iterable)、迭代器(iterator)、生成器(generator)等,几个概念混杂不清,这篇文章将梳理下这几个概念。
可迭代对象(iterable)
在Python中,str、list、set、dict、file、socket数据类型都是可以被迭代,因此凡是可以返回一个迭代器的对象都可称为可迭代对象。
>>> x = [1, 2, 3]
>>> y = iter(x)
>>> z = iter(x)
>>> next(y)
1
>>>
next(y)
2
>>>
next(z)
1
>>>
type(x)
<class 'list'
>>>> type(y)
<class 'list_iterator'>
这里x是一个可迭代对象,可迭代对象实现了__iter__方法,该方法返回一个迭代器对象
迭代器(iterator)
迭代器是一个可以记住遍历位置的对象,对象从集合的第一个元素开始访问,直到访问结束,只能往前不能回退。能在调用next()方法的时候返回下一个值,任何实现__iter__和__next__()方法的对象都是迭代器。
__iter__返回迭代器本身,__next__()返回下一个值,如果没有下一个值,则抛出StopIteration异常。因此迭代器就是实现了工厂模式的对象,在每次访问需要下一个值的时候都返回。
iter() 和 next()
int_list = [1,2,3,4]
new_list = iter(int_list) # 创建迭代器对象
print next(new_list)
迭代器对象可以使用for进行遍历
int_list = [1,2,3,4]
new_list = iter(int_list) # 创建迭代器对象
for x in new_list:
print x
可以使用next()函数
import sys
int_list = [1,2,3,4]
new_list = iter(int_list) # 创建迭代器对象
while Ture:
try:
print next(new_list)
except StopIteration:
sys.exit()
生成无限序列:
>>> from itertools import count
>>> counter = count(start=13)
>>> next(counter)
13
>>> next(counter)
14
从一个有限序列生成无限序列:
>>> from itertools import cycle
>>> colors = cycle(['red', 'white', 'blue'])
>>> next(colors)
'red'
>>> next(colors)
'white'
>>> next(colors)
'blue'
>>> next(colors)
'red'
从一个无限序列生成有限序列:
>>> from itertools import islice
>>> colors = cycle(['red', 'white', 'blue']) # infinite
>>> limited = islice(colors, 0, 4) # finite
>>> for x in limited:
... print(x)
red
white
blue
red
直观的感受一个迭代器:
class Fib:
def __init__(self):
self.prev = 0
self.curr = 1
def __iter__(self):
return self
def __next__(self):
value = self.curr
self.curr += self.prev
self.prev = value
return value>>>
f = Fib()
>>> list(islice(f, 0, 10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Fib是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器(实现了__next__方法).
生成器(generator)
生成器在Python中是最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过生成器更加的优雅,它不需要__iter__()和__next__()方法,只要使用了yield的函数就被称为生成器(generator),跟普通函数不同的是,生成器返回的是一个迭代器,只能用于迭代操作(可以理解生成器就是一个迭代器),在调用的过程中,当遇到yield时函数会暂停并保存当前所有运行的状态,返回yield的值,并在下一次next()方法时从当前位置继续执行。
def Fibonacci(num):
a, b = 0,1
while num > 0:
yield b
a ,b = b, a+b
num -= 1
for i in Fibonacci(10):
print i
生成器表达式(generator expression)
>>> a = (x*x for x in range(10))
>>> a
<generator object <genexpr> at 0x401f08
>>>> sum(a)
285
总结
可迭代对象实现__iter__方法,该方法返回一个迭代器对象
迭代器有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__()和__iter__()方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果
生成器是一种特殊的迭代器,他返回值不是通过return而是yield
参考文档: https://docs.python.org/2/library/stdtypes.html#iterator-types