-
练习: 说出如下代码的打印结果
>>> def foo():
... print(111)
... yield 222
... print(333)
... yield 444
... print(555)
>>> n = foo()
>>> next(n)
>>> next(n)
>>> next(n)
-
generator: 生成器是一种特殊的迭代器, 不需要自定义
__iter__
和__next__
-
生成器函数 (yield)
-
生成器表达式
-
class Range:
def __init__(self, start, end=None, step=1):
if end is None:
self.end = start
self.start = 0
else:
self.start = start
self.end = end
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.start < self.end:
current = self.start
self.start += self.step
return current
else:
raise StopIteration()
-
iterator: 任何实现了
__iter__
和__next__
方法的对象都是迭代器.-
__iter__
得到一个迭代器。迭代器的__iter__()
返回自身 -
__next__
返回迭代器下一个值 -
如果容器中没有更多元素, 则抛出 StopIteration 异常
-
Python2中没有
__next__()
, 而是next()
-
-
str / bytes / list / tuple / dict / set
自身不是迭代器,他们自身不具备__next__()
, 但是具有__iter__()
,__iter__()
方法用来把自身转换成一个迭代器 -
练习1: 定义一个随机数迭代器, 随机范围为 [1, 50], 最大迭代次数 30
import random
class RandomIter:
def __init__(self, start, end, times):
self.start = start
self.end = end
self.count = times
def __iter__(self):
return self
def __next__(self):
self.count -= 1
if self.count >= 0:
return random.randint(self.start, self.end)
else:
raise StopIteration()
-
练习2: 自定义一个迭代器, 实现斐波那契数列
class Fib:
def __init__(self, max_value):
self.prev = 0
self.curr = 1
self.max_value = max_value
def __iter__(self):
return self
def __next__(self):
if self.curr <= self.max_value:
res = self.curr
self.prev, self.curr = self.curr, self.prev + self.curr # 为下一次做准备
return res
else:
raise StopIteration()
-
练习3: 自定义一个生成器函数, 实现斐波那契数列
def fib(max_value):
prev = 0
curr = 1
while curr < max_value:
yield curr
prev, curr = curr, curr + prev
-
迭代器、生成器有什么好处?
-
节省内存
-
惰性求值 (惰性求值思想来自于 Lisp 语言)
-
-
各种推导式
-
分三部分:生成值的表达式, 循环主体, 过滤条件表达式
-
列表:
[i * 3 for i in range(5) if i % 2 == 0]
-
字典:
{i: i + 3 for i in range(5)}
-
集合:
-