Python中生成器generator和迭代器Iterator的使用方法

一、生成器

1. 生成器的定義

  • 把所需要值得計算方法儲存起來,不會先直接生成數值,而是等到什麼時候使用什麼時候生成,每次生成一個,減少計算機佔用內存空間

2. 生成器的創建方式

  • 第一種只要把一個列表生成式的 [ ] 改成 ( )
ret = (n + 1 for n in range(0,10))
# 返回值是生成了一個生成器對象<genexpr>儲存在16進制的地址中<generator object <genexpr> at 0x7f909f4be150>
# 如果調用次數超過生成器內值的總數量,會報錯
  • 第二種方法使用yield創建生成器
  • 只要在一個函數中存在至少一個yield關鍵字,該函數就不是普通函數,是一個生成器
  • 返回一個對象,需要使用變量接收
  • 生成器可以用for進行遍歷得到所有的值
# 定義一個斐波那契數列的生成器
def creatnum():
    print('-----start------')
    a,b = 0,1
    for i in range(5):
        print('----1-----')
        # 每次執行函數都會停在此處,並將b值返回
        yield b
        print('----2-----')
        a,b = b,a+b
        print('----3-----')
    print('-----stop-----')

f = creatnum()
print(next(f))
print(next(f))
print(next(f))
print(next(f))
print(next(f))
  • 打印結果
-----start------
----1-----
1
----2-----
----3-----
----1-----
1
----2-----
----3-----
----1-----
2
----2-----
----3-----
----1-----
3
----2-----
----3-----
----1-----
5

3. 啓動生成器的方法

  • 第一種:
next(生成器的名稱)
  • 第二種:
# 生成器第一次調用時儘量不要使用send,非要使用必須用send(None)
send()方法

二、迭代器

  1. 可迭代數據類型(具有可迭代功能)

    • 把可以通過for...in...這類語句迭代讀取一條數據供我們使用的對象稱之爲可迭代對象(Iterable)
      例如:列表,元組,字典,集合等數據類型,但他們不是可迭代對象
    • generator(生成器)
      • yield
      • 列表生成器
      • 生成器都是可迭代對象
  2. 如何判斷一個對象是不是有可迭代功能

    from collections import Iterator
    # 列表是可迭代的
    result = isinstance([1,2], Iterable)
    print(result)
    # isinstance函數會返回一個bool值 True爲可迭代,反之False
    
  3. 將具有迭代功能的數據類型轉化爲可迭代器

    • 可以被next()調用並不斷返回下一個值的對象稱之爲迭代器Iterator
  4. 迭代器的判斷方式

    from collections import Iterator 
    # 列表是可迭代對象
    # isinstance函數會返回一個bool值 True爲迭代器,反之False
    result = isinstance([1,2], Iterator)
    print(result)
    
    
  5. 可迭代對象的本質

    • 我們分析對可迭代對象進行迭代使用的過程,發現每迭代一次(即在for...in...中每循環一次)都會返回對象中的下一條數據,一直向後讀取數據直到迭代了所有數據後結束。那麼,在這個過程中就應該有一個“人”去記錄每次訪問到了第幾條數據,以便每次迭代都可以返回下一條數據。我們把這個能幫助我們進行數據迭代的“人”稱爲迭代器(Iterator)。

    • 可迭代對象的本質就是可以向我們提供一個這樣的中間“人”即迭代器幫助我們對其進行迭代遍歷使用。

    • 可迭代對象通過__iter__方法向我們提供一個迭代器,我們在迭代一個可迭代對象的時候,實際上就是先獲取該對象提供的一個迭代器,然後通過這個迭代器來依次獲取對象中的每一個數據.

    • 那麼也就是說,一個具備了__iter__方法的對象,就是一個可迭代對象。

    from collections import Iterable
    # 使用isinstance() 函數檢測某個對象是否是一個可迭代的對象
    
    
    class MyClass(object):
        # 可迭代對象的本質是,類中是否定義了 __iter__() 方法
        def __iter__(self):
            return self
    
    
    c1 = MyClass()
    # 對象c1不是可迭代對象
    result = isinstance(c1, Iterable)
    print(result)
    
  • 舉例說明迭代器本質原理

    比如,數學中有個著名的斐波拉契數列(Fibonacci),數列中第一個數爲0,第二個數爲1,其後的每一個數都可由前兩個數相加得到: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
    現在我們想要通過for...in...循環來遍歷迭代斐波那契數列中的前n個數。那麼這個斐波那契數列我們就可以用迭代器來實現,每次迭代都通過數學計算來生成下一個數。

class Fibonacci():

    def __init__(self, num):
        # 通過構造方法,保存num到類的成員屬性中
        self.num = num
        # 定義變量保存斐波那契數列前兩個值
        self.a = 0
        self.b = 1

        # 記錄當前的變量值
        self.current_index = 0

    def __iter__(self):
        # 返回迭代器,因自身就是迭代器,故可以返回自己
        return self

    def __next__(self):

        # 判斷是否生成完畢
        if self.current_index < self.num:
            # 返回
            result = self.a

            # 交換兩個變量值
            self.a, self.b = self.b, self.a+self.b

            self.current_index += 1

            return result

        else:
            # 停止迭代
            raise StopIteration


if __name__ == '__main__':
    # 創建迭代器
    fib_iterator = Fibonacci(5)

    # 使用迭代器,輸出斐波那契數列值
    for value in fib_iterator:
        print(value, end=" ")

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章