python语法31[iterator和generator+yield]
一 iterator迭代器
(1)在python2.x中,next方法,在python3.x中,为__next__(),返回容器的下一个元素
(2)__iter__方法,返回迭代器自身
2)iterator的使用
for e in [2, 4, 8, 16] :
print(e)
for c in 'ABCDEFG' :
print (c)
#use list iterator
for line in open("test.txt").readlines():
print (line )
#use file iterator, and it is better. not read all data into memory
for line in open("test.txt"):
print (line )
#TestIterator()
3) 自定义iterator类型
python2.7 实例:
def __init__(self, step):
self.step = step
def next(self):
if self.step==0:
raise StopIteration
self.step-=1
return self.step
def __iter__(self):
return self
myI = MyIterator(4)
for e in myI:
print e
在python2.7下运行正常,但是在3.1下有next需要改为__next__,有错误如下:TypeError: iter() returned non-iterator of type 'MyIterator'
python3.1代码如下:
def __init__(self, step):
self.step = step
def __next__(self):
if self.step==0:
raise StopIteration
self.step-=1
return self.step
def __iter__(self):
return self
myI = MyIterator(4)
for e in myI:
print (e)
二 generator
1. 有yield关键字的函数则会被识别为generator函数,此时其实函数返回的仍然是iterator。
2. generator函数用来生成一个序列,但不是一次完成,而是经过多次调用:调用generator函数得到一个generator的对象。之后每次调用generator的next()或__next__()方法都会得到序列的下一个值。
3. 如何做到的?
generator的next()或__next__()导致generator函数被调用,遇到yield,返回序列一个值,然后generator函数挂起。下一个next()或__next__()让generator函数恢复,从挂起处往后继续执行。
这样做的好处之一是不必一次生成序列所有元素(例如序列很长时,存所有元素并不好),而是像有一个iterator一样一个个生成。
1)实例
for e in l:
print ("before yield:" + str(e))
yield e
print ("after yield:" + str(e))
for el in TestGenerator([6,7,8,9]):
print (el)
#break
运行结果如下:
before yield:6
6
after yield:6
before yield:7
7
after yield:7
before yield:8
8
after yield:8
before yield:9
9
after yield:9
2)实例
for e in l:
print ("before yield:" + str(e))
enew = yield e
print ("after yield:" + str(enew))
it = Generator2([6,7,8,9])
for i in range(6,10):
if i == 8 :
element = it.send(800)
else:
element = it.next()
print(element)
在python2.7下运行正常,但是在3.1下需要next()改为__next__(),否则有错误如下:AttributeError: 'generator' object has no attribute 'next'
运行结果:
before yield:6
6
after yield:None
before yield:7
7
after yield:800
before yield:8
8
after yield:None
before yield:9
9
3)实例
i = 0
while i < maximum:
val = (yield i)
# If value provided, change counter
if val is not None:
i = val
else:
i += 1
def TestCounter():
co = counter(10)
for e in co:
print (e)
if(e == 2):
co.send(8)
TestCounter()
运行结果:
0
1
2
9
4)next()或__next__()和send()方法作用大致是相同,next()或__next__()相当于send(None)。
参考:
http://www.lfyzjck.com/2010-10-23/360.html
http://www.tech126.com/python-yileld/
http://lukejin.javaeye.com/blog/587051
http://www.i7xh.com/2009/10/22/py_iter/
http://blog.csdn.net/chszs/archive/2009/01/24/3852669.aspx
http://hi.baidu.com/uestcfb/blog/item/4f138fd314ed26043bf3cfd3.html
完!