1. 程式人生 > >Python學習筆記——叠代器和生成器

Python學習筆記——叠代器和生成器

返回對象 node manual 通過 line 計數 bject repr 對象

1、手動遍歷叠代器

  使用next函數,並捕獲StopIteration異常。

def manual_iter():
    with open(./test.py) as f:
        try:
            while True:
                line = next(f)
                print line
        except StopIteration:
            pass

next函數也可以指定值來標記結尾

def manual_iter():
    with open(./test.py) as f:
        
try: while True: line = next(f, None) if line == None: break print line except StopIteration: pass

  使用for循環操作叠代器就不用考慮StopIteration異常,底層自動處理這些細節

2、代理叠代

使用iter來返回指定對象的叠代,iter(s)只是簡單的通過調用 s.__iter__() 方法來返回對應的叠代器對象

class Node:
    def __init__(self, value):
        self._value = value
        self._children = []

    def __repr__(self):
        return Node({!r}).format(self._value)

    def add_child(self, node):
        self._children.append(node)

    def __iter__(self):
        return iter(self._children)

node1 
= Node(1) node2 = Node(2) root = Node(root) root.add_child(node1) root.add_child(node2)

i = iter(root)
print next(i)
print next(i)

for n in root:
print n
 

  需要註意的是,實現了__iter__()可以使用for循環,但是不能直接使用next()進行調用,要想使用next,必須先調用root.iter()

3、實現叠代器協議

Python的叠代協議要求一個 __iter__() 方法返回一個特殊的叠代器對象, 這個叠代器對象實現了next 方法,註意python3中是__next__方法。並通過 StopIteration 異常標識叠代的完成。最簡單的方式就是代理叠代中使用的方式。還有一種方式就是__iter__()返回對象本身,該對象實現next()方法。

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化兩個計數器a,b

    def __iter__(self):
        return self # 實例本身就是叠代對象,故返回自己

    def next_(self): # 在python3中,為__next__()
        self.a, self.b = self.b, self.a + self.b # 計算下一個值
        if self.a > 100000: # 退出循環的條件
            raise StopIteration()
        return self.a # 返回下一個值

4、反向叠代

  使用內置的reversed可以實現反向叠代,前提是對象大小可以確定,或者實現了__reversed__方法。

a = [1, 2, 3, 4]
for x in reversed(a):
    print x

  使用__reversed__方法

class Countdown:
    def __init__(self, start):
        self.start = start

    # Forward iterator
    def __iter__(self):
        n = self.start
        while n > 0:
            yield n
            n -= 1

    # Reverse iterator
    def __reversed__(self):
        n = 1
        while n <= self.start:
            yield n
            n += 1

for rr in reversed(Countdown(30)):
    print rr
for rr in Countdown(30):
    print rr

5、叠代器切片

  對叠代器進行切片操作,可以使用itertools.islice()方法來實現,函數 islice() 返回一個可以生成指定元素的叠代器,它通過遍歷並丟棄直到切片開始索引位置的所有元素。 然後才開始一個個的返回元素,並直到切片結束索引位置。

def count(n):
    while True:
        yield n
        n += 1
c = count(10)
import itertools
for x in itertools.islice(c, 10, 20):
    print x

Python學習筆記——叠代器和生成器