本文实例讲述了Python iter()函数用法。分享给大家供大家参考,具体如下:
python中的迭代器用起来非常灵巧,不仅可以迭代序列,也可以迭代表现出序列行为的对象,例如字典的键、一个文件的行,等等。
迭代器就是有一个next()
方法的对象,而不是通过索引来计数。当使用一个循环机制需要下一个项时,调用迭代器的next()方法,迭代完后引发一个StopIteration异常。
但是迭代器只能向后移动、不能回到开始、再次迭代只能创建另一个新的迭代对象。
反序迭代工具:reversed()
将返回一个反序访问的迭代器。python中提供的迭代模块:itertools模块
先看几个例子:
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> l = [ 2 , 3 , 4 ] >>> iterl = iter (l) >>> iterl. next () 2 >>> iterl. next () 3 >>> iterl. next () 4 >>> iterl. next () Traceback (most recent call last): File "<stdin>" , line 1 , in <module> StopIteration |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
>>> d = { 'one' : 1 , 'two' : 2 , 'three' : 3 } >>> d { 'three' : 3 , 'two' : 2 , 'one' : 1 } >>> iterd = iter (d) #字典的迭代器会遍历字典的键(key) >>> iterd. next () 'three' >>> iterd. next () 'two' >>> iterd. next () 'one' >>> iterd. next () Traceback (most recent call last): File "<stdin>" , line 1 , in <module> StopIteration |
下面查看iter()函数的帮助信息:
1
2
3
4
5
6
7
8
|
>>> help ( iter ) Help on built - in function iter in module __builtin__: iter (...) iter (collection) - > iterator iter ( callable , sentinel) - > iterator Get an iterator from an object . In the first form, the argument must supply its own iterator, or be a sequence. In the second form, the callable is called until it returns the sentinel. |
iter()
函数有两种用法,一种是传一个参数,一种是传两个参数。结果都是返回一个iterator对象。
所谓的iterator对象,就是有个next()方法的对象。next方法的惯例或约定(convention)是,每执行一次就返回下一个值(因此它要自己记录状态,通常是在iterator对象上记录),直到没有值的时候raiseStopIteration。
传1个参数:参数collection应是一个容器,支持迭代协议(即定义有__iter__()
函数),或者支持序列访问协议(即定义有__getitem__()
函数),否则会返回TypeError异常。
传2个参数:当第二个参数sentinel出现时,参数callable应是一个可调用对象(实例),即定义了__call__()
方法,当枚举到的值等于哨兵时,就会抛出异常StopIteration。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
>>> s = 'abc' #s支持序列访问协议,它有__getitem__()方法 >>> help ( str .__getitem__) Help on wrapper_descriptor: __getitem__(...) x.__getitem__(y) < = = > x[y] >>> s.__getitem__( 1 ) 'b' >>> s[ 1 ] 'b' >>> iters = iter (s) #iters是一个iterator对象,它有next()和__iter__()方法 >>> iters1 = iters.__iter__() >>> iters2 = iter (iters) >>> iters <iterator object at 0x030612D0 > >>> iters1 <iterator object at 0x030612D0 > >>> iters2 <iterator object at 0x030612D0 > iters iters1 iters2 是同一个迭代器!! >>> iters. next () 'a' >>> iters. next () 'b' >>> iters. next () 'c' >>> iters. next () Traceback (most recent call last): File "<stdin>" , line 1 , in <module> StopIteration |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
>>> class test: # test 类支持迭代协议,因为它定义有__iter__()函数 ... def __iter__( self ): ... print '__iter__ is called!' ... self .result = [ 1 , 2 , 3 ] ... return iter ( self .result) ... >>> t = test() # t支持迭代协议 >>> for i in t: #当执行for i in t 时,实际上是调用了t.__iter__(),也就是__iter__(t),返回一个iterator对象 ... print i, ... __iter__ is called! 1 2 3 >>> for i in t.__iter__(): print i, __iter__ is called!! 1 2 3 >>> for i in test.__iter__(t): print i, __iter__ is called!! 1 2 3 >>> l = [ 1 , 2 , 3 ] >>> for i in l: ... print i, ... 1 2 3 |
1
2
3
4
5
6
7
8
9
10
|
#上述for循环实际上是这样工作的(for循环会自动调用迭代器的next()方法),如下: >>> iterl = iter (l) >>> while True : ... try : ... i = iterl. next () ... except StopIteration: ... break ... print i, ... 1 2 3 |
1
2
3
4
5
6
7
8
9
10
|
>>> f = open (r 'C:\Users\Administrator\Desktop\test.txt' , 'w' ) >>> f.writelines([ 'love python\n' , 'hello python\n' , 'love python\n' ]) >>> f.close() >>> f = open (r 'C:\Users\Administrator\Desktop\test.txt' , 'r' ) >>> for line in f: # 文件对象生成的迭代器会自动调用readline()方法,这样循环遍历就可以访问文本文件的所有行 ... print line[: - 1 ] ... love python hello python love python |
上述for循环部分功能与以下代码一致:
1
2
3
4
5
6
7
8
9
10
|
>>> while True : ... line = f.readline() ... if line! = '': ... print line[: - 1 ] ... else : ... break ... love python hello python love python |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
>>> f = open (r 'C:\Users\91135\Desktop\test.txt' , 'r' ) >>> f.readlines() [ 'love python\n' , 'hello python\n' , '\n' , 'love python\n' ] >>> f.seek( 0 ) >>> f. next () 'love python\n' >>> f. next () 'hello python\n' >>> f. next () '\n' >>> f. next () 'love python\n' >>> f. next () Traceback (most recent call last): File "<pyshell#140>" , line 1 , in <module> f. next () StopIteration >>> f.seek( 0 ) >>> it1 = iter (f) >>> it2 = f.__iter__() |
f iter1 iter2 三者是同一个对象!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
>>> f < open file 'C:\\Users\\91135\\Desktop\\test.txt' , mode 'r' at 0x030E9A70 > >>> it1 < open file 'C:\\Users\\91135\\Desktop\\test.txt' , mode 'r' at 0x030E9A70 > >>> it2 < open file 'C:\\Users\\91135\\Desktop\\test.txt' , mode 'r' at 0x030E9A70 > >>> f. next () 'love python\n' >>> it1. next () 'hello python\n' >>> next (it2) '\n' >>> next (f) 'love python\n' >>> next (f) Traceback (most recent call last): File "<pyshell#247>" , line 1 , in <module> next (f) StopIteration >>> it1. next () Traceback (most recent call last): File "<pyshell#248>" , line 1 , in <module> it1. next () StopIteration >>> it2. next () Traceback (most recent call last): File "<pyshell#249>" , line 1 , in <module> it2. next () StopIteration |
1
|
iter ( callable , sentinel) - > iterator |
如果是传递两个参数给 iter()
, 第一个参数必须是callable ,它会重复地调用第一个参数,
直到迭代器的下个值等于sentinel:即在之后的迭代之中,迭代出来sentinel就立马停止。
关于Python中,啥是可调用的,可以参考:python callable()函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
>>> class IT( object ): def __init__( self ): self .l = [ 1 , 2 , 3 , 4 , 5 ] self .i = iter ( self .l) def __call__( self ): #定义了__call__方法的类的实例是可调用的 item = next ( self .i) print "__call__ is called,which would return" ,item return item def __iter__( self ): #支持迭代协议(即定义有__iter__()函数) print "__iter__ is called!!" return iter ( self .l) >>> it = IT() #it是可调用的 >>> it1 = iter (it, 3 ) #it必须是callable的,否则无法返回callable_iterator >>> callable (it) True >>> it1 < callable - iterator object at 0x0306DD90 > >>> for i in it1: print i __call__ is called,which would return 1 1 __call__ is called,which would return 2 2 __call__ is called,which would return 3 |
可以看到传入两个参数得到的it1的类型是一个callable_iterator,它每次在调用的时候,都会调用__call__
函数,并且最后输出3就停止了。
1
2
3
4
5
6
7
|
>>> it2 = iter (it) __iter__ is called!! >>> it2 <listiterator object at 0x030A1FD0 > >>> for i in it2: print i, 1 2 3 4 5 |
与it1相比,it2就简单的多,it把自己类中一个容器的迭代器返回就可以了。
上面的例子只是为了介绍iter()函数传两个参数的功能而写,如果真正想写一个iterator的类,还需要定义next函数,这个函数每次返回一个值就可以实现迭代了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
>>> class Next (): def __init__( self ,data = 825 ): self .data = data def __iter__( self ): return self def next ( self ): print "next is called!!" if self .data> 828 : raise StopIteration else : self .data + = 1 return self .data >>> for i in Next (): print i next is called!! 826 next is called!! 827 next is called!! 828 next is called!! 829 next is called!! >>> for i in Next ( 826 ): print i next is called!! 827 next is called!! 828 next is called!! 829 next is called!! >>> |
唯一需要注意下的就是next中必须控制iterator的结束条件,不然就死循环了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
>>> it = Next () >>> it.__iter__() <__main__. Next instance at 0x02E75F80 > >>> Next .__iter__(it) <__main__. Next instance at 0x02E75F80 > >>> iter (it) <__main__. Next instance at 0x02E75F80 > >>> it <__main__. Next instance at 0x02E75F80 > >>> it = Next () >>> it. next () next is called!! 826 >>> next (it) next is called!! 827 >>> Next . next (it) next is called!! 828 >>> next (it) next is called!! 829 >>> it. next () next is called!! Traceback (most recent call last): File "<pyshell#68>" , line 1 , in <module> it. next () File "<pyshell#1>" , line 9 , in next raise StopIteration StopIteration |
希望本文所述对大家Python程序设计有所帮助。
原文链接:http://blog.csdn.net/sxingming/article/details/51479039