一.迭代器(iterator)
- 迭代器 :任何实现了
__iter__
和__next__
方法的对象都是迭代器.
1.
__iter__
得到一个迭代器。迭代器的__iter__()
返回自身
2.__next__
返回迭代器下一个值
3.如果容器中没有更多元素, 则抛出 StopIteration 异常
4.Python2中没有__next__()
, 而是 next()
- 可迭代对象
实现了
__iter__
方法,但是没有实现__next__
方法的对象.__iter__
会把自身转变为一个可迭代对象.这样的话就可以用for循环去遍历它.
str/ bytes/ list/ dict/ tuple/set 都是可迭代对象, 自身不是迭代器.
例1.使用迭代器,实现原生的range功能.
class Range:
def __init__(self, start, stop=None, step=1):
if stop is None:
self.start = 0
self.stop = start
else:
self.start = start
self.stop = stop
self.step = step
def __iter__(self):
return self
def __next__(self):
# 每次循环返回当前的值.
if self.start < self.stop:
# 更新self.start
res = self.start
self.start = self.start + self.step
return res
else:
raise StopIteration()
for i in Range(10):
print(i) # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
例2:使用迭代器,实现原生的randint功能.
import random
class Randomint:
def __init__(self, start, end, times):
self.start = start
self.end = end
self.times = times
def __iter__(self):
return self
def __next__(self):
if self.times > 0:
self.times -= 1
return random.randint(self.start, self.end)
else:
raise StopIteration()
for i in Randomint(1, 50, 10):
print(i) # 14, 35, 49, 29, 30, 14, 48, 25, 49, 41
二.生成器(generator)
- 生成器就是函数内部通过yield来返回,没有return的函数.
生成器是一种特殊的迭代器, 不需要自定义
__iter__
和__next__
例3.分别使用迭代器和生成器实现斐波那契数列
使用迭代器实现斐波那契数列
class Fab:
def __init__(self, max_iter):
self.prev = 0
self.curr = 1
self.max_iter = max_iter
def __iter__(self):
return self
def __next__(self):
# 判断有没有超出最大迭代次数
if self.max_iter > 0:
self.max_iter -= 1
res = self.curr
# 更新当前值和前一个值
self.curr, self.prev = self.curr + self.prev, self.curr
return res
else:
raise StopIteration()
使用生成器实现斐波那契数列
def fab(max_iter):
curr = 1
prev = 0
while max_iter > 0:
res = curr
curr, prev = curr + prev, curr
max_iter -= 1
yield res
- 迭代器、生成器有什么好处?
节省内存
惰性求值 (惰性求值思想来自于 Lisp 语言)
- 各种推导式
分三部分:生成值的表达式, 循环主体, 过滤条件表达式
列表: [i * 3 for i in range(5) if i % 2 == 0]
字典: {i: i + 3 for i in range(5)}
集合: {i for i in range(5)}
网友评论