本文实例讲述了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