python列表產生式&產生器&迭代器

來源:互聯網
上載者:User

標籤:last   lis   做了   while   方式   執行流程   for迴圈   代碼   font   

一、列表產生式

什麼是列表產生式?

列表產生式是快速產生列表的一種方式。(貌似有些廢話)

更專業點的說法:列表產生式即List Comprehensions,是Python內建的非常簡單卻強大的可以用來建立list的產生式。

在python2.7裡

舉個例子,要產生list [1,2,3,4,5],可以用range(1,6)

>>> range(1,6)[1, 2, 3, 4, 5]

但是如果要產生[1x1,2x2,3x3,4x4,5x5]怎麼做呢?

普通青年做法:

>>> L = []>>> for x in range(1,6):...     L.append(x*x)... >>> L[1, 4, 9, 16, 25]

但是這種方式,太繁瑣、也太LOW,用列表產生式一行代碼搞定:

>>> [ x*x for x in range(1,6) ][1, 4, 9, 16, 25]  

在python3裡

>>> range(1,6)range(1, 6)>>> L = []>>> for x in range(1,6):...     L.append(x*x)... >>> L[1, 4, 9, 16, 25]>>> [ x*x for x in range(1,6) ][1, 4, 9, 16, 25]

說明:

python2中的range返回的是一個列表

python3中的range返回的是一個迭代值

 

二、產生器

通過列表產生式,我們可以直接建立一個列表。但是,受到記憶體限制,列表容量肯定是有限的。而且,建立一個包含100萬個元素的列表,不僅佔用很大的儲存空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。

所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素呢?這樣就不必建立完整的list,從而節省大量的空間。在Python中,這種一邊迴圈一邊計算的機制,稱為產生器:generator。

如何建立產生器呢?

方法一:(把列表產生式的[]變為(),就建立了一個generator)

>>> L = [x * x for x in range(8)]>>> L[0, 1, 4, 9, 16, 25, 36, 49]>>> S = (x * x for x in range(8))>>> S<generator object <genexpr> at 0xb7102fcc>>>> 

如何列印generator的每一個元素呢?

方法一:>>> next(S)0>>> next(S)1>>> next(S)4>>> next(S)9>>> next(S)16>>> next(S)25>>> next(S)36>>> next(S)49>>> next(S)Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration>>> # 使用next方法來擷取下一回的傳回值,最終找不到更多的元素時,會拋出StopIteration錯誤。#更好的方式,推薦使用for迴圈來擷取元素值>>> S = (x * x for x in range(8))>>> for n in S:...     print(n)... 014916253649>>> 

  

方法二:函數(推算的演算法比較複雜,用類似列表產生式的for迴圈無法實現的時候,還可以用函數來實現)


最著名的例子:斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個數都可由前兩個數相加得到:

1, 1, 2, 3, 5, 8, 13, 21, 34, 55...

def fib(max):    n,a,b = 0,0,1    while n < max:        #print(b)        yield  b        a,b = b,a+b        n += 1    return "over"#一個函數定義中包含yield關鍵字,那麼這個函數就不再是一個普通函數,而是一個generator>>> f = fib(6)>>> f<generator object fib at 0x104feaaa0>

最難理解的就是generator和函數的執行流程不一樣。函數是順序執行,遇到return語句或者最後一行函數語句就返回。

而變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。

# next方法擷取值>>>data = fib(10)>>>print(data)>>>print(data.__next__())#更好的方式>>> for n in fib(6):...     print(n)...112358# return 值只有在發生StopIteration錯誤時,才返回>>> list = fib(6)>>> while True:...     try:...         x = next(list)...         print(‘list:‘, x)...     except StopIteration as e:...         print(‘return value:‘, e.value)...         break...list: 1list: 1list: 2list: 3list: 5list: 8return value: over

  

擴充:

yield實現在單線程的情況下實現並發運算的效果
import timedef consumer(name):    print("%s 準備吃包子啦!" % name)    while True:        baozi = yield        print("包子[%s]來了,被[%s]吃了" % (baozi,name))#c = consumer("R")#c.__next__()#c.__next__()def producer(name):    c = consumer(‘A‘)    c2 = consumer("B")    c.__next__()    c2.__next__()    print("老子開始準備做包子了")    for i in range(10):        time.sleep(1)        print("做了2個包子")        c.send(i)        c2.send(i)producer("coco")

  

三、迭代器

可迭代對象:可作用於for迴圈的對象都是可迭代對象(Iterable)

迭代器:可以被next()函數調用並不斷返回下一個值的對象稱為迭代器(Iterator),它們表示一個惰性計算的序列

判斷是否是可迭代類型:

# 可迭代類型:list、tuple、dict、set、str、generator>>> from collections import Iterable>>> isinstance([],Iterable)True>>> isinstance([1,2,3],Iterable)True>>> isinstance({},Iterable)True>>> isinstance((),Iterable)True>>> isinstance((4,5,6),Iterable)True>>> isinstance({},Iterable)True>>> isinstance(‘coco‘,Iterable)True>>> isinstance((x*x for x in range(1,6)),Iterable)True>>> isinstance(200,Iterable)False>>> 

 

判斷是否是迭代器:

# 產生器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator>>> from collections import Iterator>>> isinstance((x for x in range(10)), Iterator)True>>> isinstance([1,2], Iterator)False>>> isinstance({}, Iterator)False>>> isinstance(‘test‘, Iterator)False# 但是可以把list、dict、str等Iterable變成Iterator可以使用iter()函數:>>> isinstance(iter([1,2]), Iterator)True>>> isinstance(iter(‘test‘), Iterator)True  

 

說明:

python的for迴圈本質上就是通過不斷調用next()函數來實現的。

# for迴圈for x in [1, 3, 5,7]:    pass# 使用next迴圈擷取值的等價寫法it = iter([1, 3, 5,7])while True:    try:        # 獲得下一個值:        x = next(it)    except StopIteration:        # 遇到StopIteration就退出迴圈        break

 

python列表產生式&產生器&迭代器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.