python中iter()函数和__iter__方法研究_Python iter()函数用法实例分析

本文实例讲述了Python iter()函数用法。分享给大家供大家参考,具体如下:

python中的迭代器用起来非常灵巧,不仅可以迭代序列,也可以迭代表现出序列行为的对象,例如字典的键、一个文件的行,等等。

迭代器就是有一个next()方法的对象,而不是通过索引来计数。当使用一个循环机制需要下一个项时,调用迭代器的next()方法,迭代完后引发一个StopIteration异常。

但是迭代器只能向后移动、不能回到开始、再次迭代只能创建另一个新的迭代对象。

反序迭代工具:reversed()将返回一个反序访问的迭代器。python中提供的迭代模块:itertools模块

先看几个例子:

>>> l=[2,3,4]

>>> iterl=iter(l)

>>> iterl.next()

2

>>> iterl.next()

3

>>> iterl.next()

4

>>> iterl.next()

Traceback (most recent call last):

File "", line 1, in

StopIteration

>>> 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 "", line 1, in

StopIteration

下面查看iter()函数的帮助信息:

>>> 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。

>>> 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

>>> iters1

>>> iters2

iters iters1 iters2 是同一个迭代器!!

>>> iters.next()

'a'

>>> iters.next()

'b'

>>> iters.next()

'c'

>>> iters.next()

Traceback (most recent call last):

File "", line 1, in

StopIteration

>>> 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

#上述for循环实际上是这样工作的(for循环会自动调用迭代器的next()方法),如下:

>>> iterl=iter(l)

>>> while True:

... try:

... i=iterl.next()

... except StopIteration:

... break

... print i,

...

1 2 3

>>> 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循环部分功能与以下代码一致:

>>> while True:

... line=f.readline()

... if line!='':

... print line[:-1]

... else:

... break

...

love python

hello python

love python

>>> 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 "", line 1, in

f.next()

StopIteration

>>> f.seek(0)

>>> it1=iter(f)

>>> it2=f.__iter__()

f    iter1    iter2 三者是同一个对象!!!

>>> f

>>> it1

>>> it2

>>> 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 "", line 1, in

next(f)

StopIteration

>>> it1.next()

Traceback (most recent call last):

File "", line 1, in

it1.next()

StopIteration

>>> it2.next()

Traceback (most recent call last):

File "", line 1, in

it2.next()

StopIteration

iter(callable, sentinel) -> iterator

如果是传递两个参数给 iter() , 第一个参数必须是callable ,它会重复地调用第一个参数,

直到迭代器的下个值等于sentinel:即在之后的迭代之中,迭代出来sentinel就立马停止。

关于Python中,啥是可调用的,可以参考:python callable()函数

>>> 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

>>> 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就停止了。

>>> it2=iter(it)

__iter__ is called!!

>>> it2

>>> for i in it2:

print i,

1 2 3 4 5

与it1相比,it2就简单的多,it把自己类中一个容器的迭代器返回就可以了。

上面的例子只是为了介绍iter()函数传两个参数的功能而写,如果真正想写一个iterator的类,还需要定义next函数,这个函数每次返回一个值就可以实现迭代了。

>>> 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的结束条件,不然就死循环了。

>>> it=Next()

>>> it.__iter__()

>>> Next.__iter__(it)

>>> iter(it)

>>> it

>>> 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 "", line 1, in

it.next()

File "", line 9, in next

raise StopIteration

StopIteration

希望本文所述对大家Python程序设计有所帮助。

你可能感兴趣的:(python中iter()函数和__iter__方法研究_Python iter()函数用法实例分析)