迭代器
迭代器协议:对象需要提供next方法,它要么返回迭代中的下一项,要么引起一个StopIteration异常。
可迭代对象:实现了迭代器协议的对象。
iter() :获得迭代器对象。
next(): 用来获取容器中的下一个元素。
__iter__
方法来返回,迭代器实例对象。
例:
class MyRange(object):
def __init__(self, n):
self.idx = 0
self.n = n
def __iter__(self):
return self
def next(self):
if self.idx < self.n:
val = self.idx
self.idx += 1
return val
else:
raise StopIteration()
class MyRange(object):
def __init__(self, n):
self.idx = 0
self.n = n
def __iter__(self):
return self
def next(self):
if self.idx < self.n:
val = self.idx
self.idx += 1
return val
else:
raise StopIteration()
生成器
生成器函数:使用yield
而不是return
返回结果。yield
一次返回一个结果,每个结果发生时,挂起函数,下次重新进入函数便从挂起处继续执行。
生成器表达式:生成器返回按需产生结果的对象,而不是构建一个结果列表。
生成器函数
例:
>>> def generation(n):
for i in range(n):
yield i ** 2
>>> for item in generation(5):
print(item)
0
1
4
9
16
生成器在每次执行到yield
时会自动挂起,等下次调用函数时会从上一次的状态继续。
如果不使用生成器,则需要在函数调用时创建一个列表。
def generation(n):
res = []
for i in range(n):
res.append(i*i)
return res
for item in genration(5):
print(item)
生成器表达式
一般用表达式创建列表是用[ ]
,如果使用了( )
则是生成器表达式,想要获取下一个值则使用next(x)
获取。
>>> x = [i*i for i in range(5)]
>>> x
[0, 1, 4, 9, 16]
>>> x = (i*i for i in range(5))
>>> x
<generator object <genexpr> at 0x7f873707c2e0>
>>> next(x)
0
>>> next(x)
1
>>> next(x)
4
生成器的小应用:查询字母出现的位置。
>>> def test(text, word):
... if text:
... yield 0
... for index, letter in enumerate(text, 1):
... if letter == word :
... yield index
...
>>> num = test("aaavdfadsfweqr",'a')
>>> num
<generator object test at 0x7f873707c350>
>>> next(num)
0
>>> next(num)
1
>>> next(num)
2
>>> next(num)
3
>>> next(num)
7
>>> next(num)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
注意:生成器只能遍历一次。