迭代器與產生器,代器產生器

來源:互聯網
上載者:User

迭代器與產生器,代器產生器
迭代器Iterable

定義

 1 class Iterable(metaclass=ABCMeta): 2  3     __slots__ = () 4  5     @abstractmethod 6     def __iter__(self): 7         while False: 8             yield None 9 10     @classmethod11     def __subclasshook__(cls, C):12         if cls is Iterable:13             if any("__iter__" in B.__dict__ for B in C.__mro__):14                 return True15         return NotImplemented

由定義可知Iterable必然包含__iter__函數

Iterator

定義

 1 class Iterator(Iterable): 2  3     __slots__ = () 4  5     @abstractmethod 6     def __next__(self): 7         'Return the next item from the iterator. When exhausted, raise StopIteration' 8         raise StopIteration 9 10     def __iter__(self):11         return self12 13     @classmethod14     def __subclasshook__(cls, C):15         if cls is Iterator:16             if (any("__next__" in B.__dict__ for B in C.__mro__) and17                 any("__iter__" in B.__dict__ for B in C.__mro__)):18                 return True19         return NotImplemented

從定義可知Iterator包含__next____iter__函數,當next超出範圍時將拋出StopIteration事件

類型關係

 

 1 #! /usr/bin/python 2 #-*-coding:utf-8-*- 3  4 from collections import Iterator,Iterable 5  6 # 迭代器 7 s = 'abc' 8 l = [1,2,3] 9 d=iter(l)10 11 print(isinstance(s,Iterable)) # True12 print(isinstance(l,Iterable)) # True13 14 print(isinstance(s,Iterator)) # False15 print(isinstance(l,Iterator)) # False16 17 print(isinstance(d,Iterable)) # True18 print(isinstance(d,Iterator)) # True

理論上你可以使用next()來執行__next__(),直到迭代器拋出StopIteration 實際上系統提供了for .. in ..的方式來解析迭代器

 

1 l = [1,2,3,4]2 for i in l:3     print(i)4     5 # 執行結果    6 # 17 # 28 # 39 # 4

 

產生器 generator

 產生器的本質是一個迭代器

 

 1 #! /usr/bin/python 2 #-*-coding:utf-8-*- 3  4 from collections import Iterator,Iterable 5  6 s = (x*2 for x in range(5)) 7 print(s) 8 print('Is Iterable:' + str(isinstance(s,Iterable))) 9 print('Is Iterator:' + str(isinstance(s,Iterator)))10 11 for x in s:12     print(x)13 14 # 執行結果    15 # <generator object <genexpr> at 0x000001E61C11F048>16 # Is Iterable:True17 # Is Iterator:True18 # 019 # 220 # 421 # 622 # 8

函數中如果存在yield 則該函數是一個產生器對象 在每一次執行next函數時該函數會在上一個yield處開始執行,並在下一個yield處返回(相當於return

 

 1 def foo(): 2     print("First") 3     yield 1 4     print("Second") 5     yield 2 6  7 f = foo() 8 print(f) 9 10 a = next(f)11 print(a)12 b = next(f)13 print(b)14 15 # <generator object foo at 0x0000020B697F50F8>16 # First17 # 118 # Second19 # 2

執行個體

 1 #! /usr/bin/python 2 #-*-coding:utf-8-*- 3  4 def add(s,x): 5     return s+x 6  7 def gen(): 8     for i in range(4): 9         yield i10 11 base = gen()12 13 # 由於gen函數中存在yield,所以14 # for 迴圈本質是建立了兩個generator object,而非執行函數15 # base = (add(i,10) for i in base)16 # base = (add(i,10) for i in base)17 for n in [1,10]:18     base = (add(i,n) for i in base)19 20 21 # 這裡才開始展開產生器22 # 第一個產生器展開23 # base = (add(i,10) for i in base)24 # base = (add(i,10) for i in range(4))25 # base = (10,11,12,13)26 #27 # 第二個產生器展開28 # base = (add(i,10) for i in (10,11,12,13))29 # base = (20,21,22,23)30 print(list(base)) # [20,21,22,23]

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.