python-生成器函数与可迭代对象

1
2
3
4
5
def f():
print('f(),1')
yield 1
print('f(),2')
yield 2
1
g = f()
1
next(g)
f(),1
1
1
next(g)
f(),2

 2
1
next(g)
# 没有下一个可迭代之后就会引发这个问题

Traceback (most recent call last)

<ipython-input-17-5f315c5de15b> in <module>()
----> 1 next(g)


StopIteration: 

生成器函数会冻结当前函数的状态,所有的变量都保存下来

1
2
3
4
# 下一行要执行的代码的位置也会保留下来
# 直到调用next()方法,以函数返回内容为参数
# 生成器会从上次离开的地方开始
# 直到StopIteration异常抛出
1
2
3
# 当然,只需要再调用一次这个生成器函数即可恢复
g = f()
next(g)
f(),1
1

实现一个类,判断给定的范围内的偶数

1
2
3
4
5
6
7
8
9
10
11
12
class demo(object):
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
for k in range(self.start, self.end + 1):
if k % 2 == 0 and k <= self.end:
yield k
else:
pass

print([x for x in demo(1, 10)])
[2, 4, 6, 8, 10]

反向迭代

1
2
# 内置函数 reverse() 返回值是一个反向的迭代器
reversed([1,2,3,4,5,])
<list_reverseiterator at 0x7fb374fe56d8>
1
# iter()方法得到正向迭代器
1
# 如果想要反向生成器 就实现__reversed__(),正向就__iter__()

对生成器进行切片

1
2
3
4
# itertools这个库对于迭代来说非常有用
from itertools import islice
# islice(f, start, stop, step=1)
# 可以将可迭代的对象直接分割,就像对字符串一样采用切片的操作一样
1
2
# 重点islice()方法会消耗可迭代对象,除非重新实例化或者通过其他方法得到原来的对象
l = [x for x in range(20)]
1
l = iter(l)
1
2
for i in islice(l,5,13):
print(i)
5
6
7
8
9
10
11
12
1
2
for i in l:
print(i)
13
14
15
16
17
18
19