python迭代器和生成器

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返回的是一个可以类似迭代器的东西.

本文总阅读量