生成器和迭代器
-
generator: ⽣成器是一种特殊的迭代器, 不需要⾃定义 __iter__ 和 __next__
⽣成器函数 (yield)
def foo():
...: print(111)
...: yield 222
...: print(333)
...: yield 444
...: print(555)
...:
In [2]: n=foo()
In [3]: next(n)
111
Out[3]: 222
In [4]: next(n)
333
Out[4]: 444
In [5]: next(n)
555
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-5-0fa053c92e6d> in <module>
----> 1 next(n)
StopIteration:
⽣成器表达式: (i*2 for i in range(5)) 这里使用的是括号(),list是[ ].
In [9]: gen = (i*2 for i in range(5))
In [10]: print(gen)
<generator object <genexpr> at 0x10e73a200>
-
iterator:任何实现了__iter__和__next__方法的对象都是迭代器
- __iter__ 得到一个迭代器。迭代器的 __iter__() 返回自身
- __next__ 返回迭代器下一个值
- 如果容器中没有更多元素, 则抛出 StopIteration 异常
- Python2中没有 __next__() , ⽽是 next()
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()
Iter = Range(1, 4)
结果:
In [10]: print(next(Iter))
1
In [11]: print(next(Iter))
2
In [12]: print(next(Iter))
3
In [13]: print(next(Iter))
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-13-2439b2fba63d> in <module>
----> 1 print(next(Iter))
<ipython-input-9-f1a6fab34350> in __next__(self)
19 return current
20 else:
---> 21 raise StopIteration()
22
23
StopIteration:
- str / bytes / list / tuple / dict / set ⾃身不是迭代器,他们自身不具备 __next__() , 但是具有 __iter__() , __iter__() 方法用来把⾃身转换成一个迭代器
练习:
# 练习1: 定义⼀一个随机数迭代器器, 随机范围为[1, 50], 最⼤大迭代次数3
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()
RandomIter = RandomIter(1,50,3)
print(next(RandomIter))
print(next(RandomIter))
print(next(RandomIter))
print(next(RandomIter))
# 练习2: ⾃定义一个⽣成器函数, 实现斐波那契数列
def fib(max_value):
prev = 0
curr = 1
while curr < max_value:
yield curr
prev, curr = curr, curr + prev
for i in fib(20):
print(i, end=' ')
结果:1 1 2 3 5 8 13
各种推导式
分三部分:⽣成值的表达式, 循环主体, 过滤条件表达式
列表: [i*3 for i in range(5) i f %2 == 0]
字典: {i: i + 3 for i in range(5)}
集合: {i for i in range(5)}
生成器: (i for i in range(5))