参考链接
廖雪峰Python教程
名词区分:
可迭代对象(Iterable)
迭代器(Iterator)
迭代(Iteration)
一、可迭代对象Iterable
凡是可以用作for循环的都是可迭代对象,包括一般的list,tuple,set,dict,str.
可迭代对象本质是数据流,一个接一个的数据,但不一定像迭代器和生成器一样记住迭代到那个点, 下一个是什么, 利用iter(obj)函数可以将list等转变为迭代器(其实是生成器), 逐个元素投出.
my_string = "Yasoob"
my_iter = iter(my_string)
next(my_iter)
# 运行结果: 'Y'
my_string = "Yasoob"
my_iter = iter(my_string)
for i in my_iter:
print(i)
#运行结果
Y
a
s
o
o
b
判断一个对象是够是可迭代对象:
from collections import Iterable
print('字符串 is Iterable ?',isinstance('abc',Iterable))
print('list is Iterable ?',isinstance([1,2,3],Iterable))
print('整数 is Iterable ?',isinstance(123,Iterable))
#运行结果
字符串 is Iterable ? True
list is Iterable ? True
整数 is Iterable ? False
遍历可迭代对象的几种方法:
#遍历字符串:
for ch in 'abc':
print(ch)
#遍历list
L = ['A','B','C']
for tmp in L:
print(tmp)
for i,value in enumerate(L):
print(i,':',value)
#遍历dict
d = {'1':'111','2':'222','3':'333'}
for key,v in d.items():
print('key:',key,'value:',v)
二、迭代器(Iterator)对象
可以被next()函数调用并不断返回下一个值的对象称为迭代器. 生成器是一种迭代器.enumurate也是迭代器(本质生成器)
可以通过isinstance(obj, Iterator) (需要事先from collections import Iterable) 来判断对象是否迭代器.迭代到没有值了返回StopIteration错误.
for循环本质是通过调用可迭代对象的iter方法获取迭代器对象,再用next方法遍历元素.
可以使用isinstance()判断一个对象是否是Iterator对象:
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
三、generator生成器对象
生成器通过生成器函数产生, 生成器函数可以通过常规的def语句来定义, 不用return而是使用yield一次返回一个结果, 返回后停在相应位置, 再次调用时继续执行生成下一个结果, 当生成器结束没有下次执行时, 返回StopIteration.
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
>>> for n in fib(6):
... print(n)
#运行结果
1
1
2
3
5
8
创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
#(x for x in range(10))该表达式产生的是生成器对象,而非列表.
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
.
.
.
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
用for循环,因为generator也是可迭代对象
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
四、list等的迭代器.
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter(obj)函数.
i.next()方法或next(i) 函数遍历迭代器
enumerate(i)
# 创建一个列表迭代器(listiterator)
i1 = iter([1, 2, 3]) # iter是Python BIF,用于生成迭代器,文档见底部
type(i1)
<type 'listiterator'>
i1
<listiterator object at 0x1cedf50>
# 创建一个字典项迭代器(dictionary-itemiterator)
d = dict(a = 1, b = 2)
i2 = d.iteritems() # 生成iterator对象,对于字典来说还有iterkeys, itervalues等方法可用
i2
<dictionary-itemiterator object at 0x1dfe208>
[e for e in d.iteritems()] # dict.iteritems方法生成的是迭代器元素为键值对形式
[('a', 1), ('b', 2)]
# 另外还有tuple/set等都可使用iter函数返回iterator对象
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
步进式访问迭代器中元素:obj.next()
i = iter(range[3])
i.next()
0
i.next()
1
next(i) # next() - python2.6新增BIF,作用同iterator.next()
2
next(i) # 无元素可迭代时,抛出StopIteration异常,可以通过捕获此异常判断是否迭代完毕
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
循环访问遍历迭代器
# 手动循环
try:
while True:
next(i) # python2.6之前版本使用iterator.next()方法
except StopIteration:
print 'Done'
# for循环
>>> i = iter(range(3))
# 以下句法叫做列表解析,这与生成器表达式类似,之后文章介绍生成器时再记
>>> [e for e in i] # for在这里不断调用next函数,直到捕获StopIteration异常后退出
[0, 1, 2]
将迭代器传递给其他函数使用
>>> list(iter(range(3)))
[0, 1, 2]
帮助迭代器实现索引功能
使用enumerate函数返回一个迭代器对象, 该对象能够生产一个元组包括(索引,值).
enumerate(iterable, start=0)
第一参数是可迭代对象包括list/dict/迭代器等, 第二个参数是索引开始的号.
>>> i = iter('abc') # python中字符串也是可迭代对象
>>> [(k, v) for k, v in enumerate(i)] # enumerate返回一个元素为tuple的iterator
[(0, 'a'), (1, 'b'), (2, 'c')]