python标准库中的函数,iter和next。iter函数用来创建一个迭代器, next函数用来从迭代器中一个个获取数据。这两个函数一般都是在一起使用。
>>> a = [1,2,3,4,5]
>>> ga = iter(a)
>>> next(ga)
1
>>> next(ga)
2
>>> next(ga)
3
>>> next(ga)
4
>>> next(ga)
5
>>> next(ga)
Traceback (most recent call last):
File "", line 1, in
StopIteration
所有数据都取出后,如果再取,就会得到StopIteration异常。
在Python中,好些内置的数据对象都可以用来作为iter函数的参数,获取一个迭代器。上面代码示例用的是list,tuple,string,set,以及dict对象都可以用来创建迭代器:
>>> d = {'a':1,'b':2,'c':3}
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> gd = iter(d)
>>> next(gd)
'a'
>>> next(gd)
'b'
>>> next(gd)
'c'
>>> next(gd)
Traceback (most recent call last):
File "", line 1, in
StopIteration
用字典对象创建迭代器,获取的元素都是字典对象的key。
查看python官方说明,你会发现,只要对象支持__iter__函数,或者__getitem__函数,就可以用来作为iter函数的参数。而next函数更简单,就是调用迭代器对象的__next__函数。
迭代器是python提供的另一种遍历对象所有元素的方法,有的时候会让代码变得很简洁,语义更清晰自然。比如在index与元素没有对齐的时候。
iter函数的第2个参数sentinel
iter函数还有第2个参数,当此参数存在时,第1个参数就必须是可调用的对象(用callable来判断对象是否可调用),而第2个参数就是sentinel(哨兵),每一次next调用此对象的时候,只要得到的值与sentinel相等,StopIteration异常被抛出。
If the second argument, sentinel, is given, then object must be a callable object. The iterator created in this case will call object with no arguments for each call to its __next__() method; if the value returned is equal to sentinel, StopIteration will be raised, otherwise the value will be returned.
import random
def cast():
return random.randint(1,6)
def trycast():
j = 0
for i in iter(cast,6):
j += 1
print(j, ':', i)
trycast()
cast函数随机返回1-6中的某个数字,就像是掷骰子。trycast就是真的在掷骰子,直到得到6为止!iter(cast,6)返回一个迭代器,在for循环中被迭代,此迭代器每次迭代时就是调用cast对象(函数),如果cast对象返回6,迭代才停止,6不会被返回,而是抛出StopIteration异常,for循环直接就处理了此异常。
每一次调用trycast函数,为了得到6,迭代的次数都不一样,请看测试效果:
E:\py>python tp1.py
1 : 1
2 : 2
3 : 4
4 : 5
5 : 5
6 : 4
E:\py>python tp1.py
E:\py>python tp1.py
1 : 2
2 : 4
3 : 4
E:\py>python tp1.py
1 : 2
2 : 3
E:\py>python tp1.py
1 : 4
2 : 1
3 : 5
4 : 2
5 : 4
6 : 5
7 : 1
8 : 1
9 : 1
10 : 1
11 : 5
12 : 4
13 : 1
14 : 4
15 : 5
16 : 4
17 : 5
18 : 5
19 : 1
20 : 1
21 : 1
22 : 5
23 : 1
24 : 2
25 : 2
26 : 5
27 : 1
最长的一次得到6,前面掷骰子的次数是27次。
next函数在这种情况下的使用是一样的,iter返回的迭代器每次next时,调用的是对象函数,直到sentinel出现。(有个iter例子,是与partial函数一起的,请参考:functools.partial的使用)
-- EOF --