python迭代器和生成器
迭代器
实现了 __iter__
方法 此方法返回一个迭代器, 可以调用next方法
class Iter(object):
def __init__(self):
self.start = 10
def next(self):
self.start += 1
if self.start > 20:
raise StopIteration
return self.start
def __iter__(self):
return self
- 实现了
next
方法和__iter__
方法 - 通过next方法可以得到下一个值
事实上,Python正是根据是否检查到这个异常来决定是否停止迭代的。
赌场发牌的荷官算是一个比较接近的例子。
本来你需要自己去处理一堆牌(一个 collection),现在你有了这个对象,只要不断问他要“下一张”,他要是有自然会给你,没有就结束(StopIteration)—引用知乎的一个例子
it = Iter()
print it.next()
print it.next()
11
12
[Finished in 0.1s]
生成器可以生成一组序列
it = Iter()
print list(it)
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
可通过for in 内部依次访问
it = Iter()
for x in it:
print x
11
12
13
14
15
16
17
18
19
20
[Finished in 0.0s]
每次迭代中返回一个元素,因此可以使用迭代器来解决复用可占空间的问题
可以通过iter方法获得 获得list迭代器
>>> lst = range(5)
>>> it = iter(lst)
>>> it
<listiterator object at 0x01A63110>
生成器
带有yield函数被称为生成器 , 返回一个可迭代的迭代器.
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
c = fab(5)
print c.next()
// 1
print c.next()
// 1
print c.next()
// 2
print c.next()
// 3
print c.next()
// 5
首先fab返回一个可以迭代的对象, 通过这个迭代对象,操作next方法访问,得到yield的返回值, 暂停。下次访问时候, yield之后继续运行。
实例:读取文件
def read_file(fpath):
BLOCK_SIZE = 1024
with open(fpath, 'rb') as f:
while True:
block = f.read(BLOCK_SIZE)
if block:
yield block
else:
raise StopIteration
path = '/Users/gougou/Desktop/test1.png'
path1 = '/Users/gougou/Desktop/test2.png'
alldata = ''
for data in read_file(path):
alldata += data
f = open(path1,'wb')
f.write(alldata)
生成器 是 含有yield的def, def返回的是一个可以类似迭代器的东西.