1. 程式人生 > >python迭代器以及生成器

python迭代器以及生成器

迭代,即重複做一些事很多次,python中通過for迴圈可以對序列、字典以及其他的物件進行迭代。在其他物件進行迭代時,需要在其他物件中實現__iter__方法。

__iter__方法返回一個迭代器,所謂的迭代器就是具有next方法的物件。在呼叫next方法時,迭代器會返回它的下一個值。如果next方法被呼叫,但迭代器沒有值可以返回,就會引發一個StopIteration異常。

用迭代器實現一個斐波那契數列

class Fab(object):
    def __init__(self,max):
        self.max = max
        self.n, self.a, self.b = 0, 0, 1

    def __iter__(self):
        return self

    def next(self):
        if self.n < self.max:
            r = self.b
            self.a, self.b = self.b, self.a + self.b
            self.n += 1
            return r
        raise StopIteration

print '迭代器的輸出結果:'
for i in Fab(5):
    print i
輸出結果:

除了能夠在迭代器和可迭代物件上進行迭代(這是經常做的)外,還能把它們轉換為序列。在大部分能夠使用序列的情況下,能使用迭代器替換。


生成器,是一種用普通的函式語法定義的迭代器,是包含yield語句的函式。除了名字不同以外,它的行為和普通函式也有很大的差別。這在於它不像return那樣產生返回值,而是每次產生多個值。每次產生一個值(使用yield語句),函式機會被凍結:即函式停在那點等待被啟用。函式被啟用後就從停止的那點開始執行。函式的本地變數和上一次執行的狀態一樣。

用生成器實現斐波那契數列。

def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1

print '生成器生成的結果:'

for i in fab(5):
    print i

用生成器解決n皇后問題。
def config(state, nextX):
    nextY = len(state)

    for i in range(nextY):
        if abs(nextX - state[i]) in (0,nextY - i):
            return True
    return False

def nQueens(num = 8, state = ()):
    if len(state) == num - 1:
        for pos in range(num):
            if not config(state, pos):
                yield (pos,)
    else:
        for pos in range(num):
            if not config(state, pos):
                for result in nQueens(num, state + (pos,)):
                    yield (pos,) + result

def prettyprint(solution):
    def line(pos, lenth = len(solution)):
        return '. '*(pos) + 'X ' + '. '*(lenth - pos -1)
    for pos in solution:
        print line(pos)

i = 1
for solution in nQueens():
    print '第%d种放置情況' % (i)
    prettyprint(solution)
    i += 1