迭代器和生成器

1.迭代器與生成器

迭代器(iterator)與生成器(generator)是 Python 中比較經常使用又很容易混淆的兩個概念,今天就把它們梳理一遍,並舉一些經常使用的例子。git

2迭代器github

for 語句與可迭代對象(iterable object):for循環就是基於迭代器協議提供了一個統一的能夠遍歷全部對象的方法,即在遍歷以前,先調用對象的__iter__方法將其轉換成一個迭代器,而後使用迭代器協議去實現循環訪問,這樣全部的對象就均可以經過for循環來遍歷了,函數

for i in [123]:bthis

print(i)spa

輸出:1code

           2orm

           3對象

obj={'a':123,'b':456}ip

for i in obj:內存

print(i)

輸出:a

           b

這些能夠用在 for 語句進行循環的對象就是可迭代對象。除了內置的數據類型(列表、元組、字符串、字典等)能夠經過 for 語句進行迭代,咱們也能夠本身建立一個容器,包含一系列元素,能夠經過 for 語句依次循環取出每個元素,這種容器就是迭代器(iterator)。除了用 for 遍歷,迭代器還能夠經過 next() 方法逐一讀取下一個元素。要建立一個迭代器有3種方法,其中前兩種分別是:

         1爲容器對象添加 __iter__()__next__() 方法(Python 2.7 中是 next());__iter__() 返回迭代器對象自己 self__next__() 則返回每次調用 next() 或迭代時的元素;

  • 2內置函數 iter() 將可迭代對象轉化爲迭代器
  • # iter(IterableObject)
    ita = iter([1, 2, 3])
    print(type(ita))
     
    print(next(ita))
    print(next(ita))
    print(next(ita))
     
    # Create iterator Object
    class Container:
        def __init__(self, start = 0, end = 0):
            self.start = start
            self.end = end
        def __iter__(self):
            print("[LOG] I made this iterator!")
            return self
        def __next__(self):
            print("[LOG] Calling __next__ method!")
            if self.start < self.end:
                i = self.start
                self.start += 1
                return i
            else:
                raise StopIteration()
    c = Container(0, 5)
    for i in c:
        print(i)
     
    [LOG] I made this iterator!
    [LOG] Calling __next__ method!
    0
    [LOG] Calling __next__ method!
    1
    [LOG] Calling __next__ method!
    2
    [LOG] Calling __next__ method!
    3
    [LOG] Calling __next__ method!
    4
    [LOG] Calling __next__ method!
    建立迭代器對象的好處是當序列長度很大時,能夠減小內存消耗,由於每次只須要記錄一個值即刻(常常看到人們介紹 Python 2.7 的 range 函數時,建議當長度太大時用 xrange 更快,在 Python 3.5 中已經去除了 xrange 只有一個相似迭代器同樣的 range)。
    3生成器
    前面說到建立迭代器有3種方法,其中第三種就是生成器(generator)。生成器經過 yield 語句快速生成迭代器,省略了複雜的 __iter__() & __next__() 方式:
    def container(start, end):
        while start < end:
            yield start
            start += 1
    c = container(0, 5)
    print(type(c))
    print(next(c))
    next(c)
    for i in c:
        print(i)

     

 

簡單來講,yield 語句可讓普通函數變成一個生成器,而且相應的 __next__() 方法返回的是 yield 後面的值。一種更直觀的解釋是:程序執行到 yield 會返回值並暫停,再次調用 next() 時會從上次暫停的地方繼續開始執行:

def gen():
    yield 5
    yield "Hello"
    yield "World"
    yield 4
for i in gen():
    print(i)

5HelloWorld4

相關文章
相關標籤/搜索