惰性求值,也就是延遲求值,表達(dá)式不會(huì)在它被綁定到變量之后就立即求值,而是等用到時(shí)再求值。這個(gè)特性可以解決一些巨大甚至無(wú)限的集合列表,如菲波那切數(shù)列、幾十G的文件等等。延遲求值的一個(gè)好處是能夠建立可計(jì)算的無(wú)限列表而沒(méi)有妨礙計(jì)算的無(wú)限循環(huán)或大小問(wèn)題。

創(chuàng)新互聯(lián)建站堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的福貢網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
Python?中的很多方法沒(méi)有直接返回列表,而是返回了一個(gè)可迭代的generator
(生成器)對(duì)象,這便是python的惰性求值,因?yàn)樵趧?chuàng)建一個(gè)很大的列表時(shí),對(duì)內(nèi)存的開(kāi)銷非常大,太大時(shí)python會(huì)直接報(bào)錯(cuò),舉個(gè):chestnut::range()方法是產(chǎn)生一個(gè)指定范圍列表,在Python3之前,該方法直接產(chǎn)生一個(gè)列表,xrange()?產(chǎn)生一個(gè)生成器:
xrange(100)
xrange(100)
range(100)
[0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
當(dāng)參數(shù)里面的值足夠大時(shí),range()產(chǎn)生了一個(gè)巨大的列表,這是內(nèi)存會(huì)吃不消,等待一段時(shí)間后程序會(huì)直接被Kill掉:
for?i?in?range(999999999999):
...
print?i
...
Killed:
9
占滿內(nèi)存
用xrange()?方法就不回出現(xiàn)這種問(wèn)題,并且可以一直運(yùn)行:
for?i?in?xrange(999999999999):
...
print?i
...
1
2
3
4
5
6
7
8
9
10...
在Python3中range已經(jīng)被改為了xrange,所以在python3中可以放心使用range().
惰性求值不要求你事先準(zhǔn)備好整個(gè)迭代過(guò)程中所有的元素。迭代器僅僅在迭代至某個(gè)元素時(shí)才計(jì)算該元素,而在這之前或之后,元素可以不存在或者被銷毀
還有前文所說(shuō)的list comprehension語(yǔ)句,在兩邊放上[],會(huì)產(chǎn)生別表,如果數(shù)據(jù)源很長(zhǎng)則會(huì)報(bào)內(nèi)存錯(cuò)誤:
print [i?for?i?in?range(9999999999999999)]
Python(1627,0x7fffe5b713c0)
malloc: *** mach_vm_map(size=80000000000000000) failed
(error?code=3)
***?error:
can't allocate region
***?set?a
breakpoint?in?malloc_error_break?to?debug
Traceback
(most recent?call?last):
File "",
line 1,?in?/spanmodule
MemoryError
這樣直接產(chǎn)生列表沒(méi)有效率,為了創(chuàng)建生成器對(duì)象,可以在list
comprehension兩邊放上(),這樣它就有了惰性求值的特性。
print((i?for?i
in?range(99999999999999)))
使用next()內(nèi)建函數(shù)訪問(wèn)生成器里的元素:
num =
(i?for?i?in?range(5))
num
next(num)
next(num)
1
for j in range(4):
...
print(next(num))
...
2
3
4
Traceback
(most recent call last):
File "",
line 2,?in?/spanmodule
StopIteration
當(dāng)訪問(wèn)到最后元素時(shí),再調(diào)用next(),Python將會(huì)拋出StopIteration異常。Python正是根據(jù)是否檢查到這個(gè)異常來(lái)決定是否停止迭代。
step1 =
someLongOperation1()step2 = someLongOperation2()step3 =
concatenate(step1, step2)
以上代碼需要分別執(zhí)行一二兩步操作,第三步用到一二兩步的結(jié)果,在Pyhton中會(huì)有序的執(zhí)行這些函數(shù):首先是?someLongOperation1,然后?someLongOperation2,最后?concatenate,如果確保沒(méi)有函數(shù)修改或依賴于全局變量,第一二步可以被并行執(zhí)行。假設(shè)我們不想并行運(yùn)行這兩個(gè)函數(shù),我們只在其他函數(shù)依賴于?step1?和?step2?時(shí)才需要執(zhí)行這兩個(gè)函數(shù)。我們甚至在concatenate?調(diào)用之前都不必執(zhí)行他們,可以把他們的求值延遲到?concatenate?函數(shù)內(nèi)實(shí)際用到他們的位置。如果函數(shù)中用到了if分支語(yǔ)句,條件無(wú)關(guān)step1和step2則可以盡量將判斷條件放前面以減少不必要的計(jì)算:
step1 =
someLongOperation1()
step2 =
someLongOperation2()if?condition:
step3 =
concatenate(step1, step2)
換為:if?condition:
step1 =
someLongOperation1()
step2 =
someLongOperation2()
step3 =
concatenate(step1, step2)
如果?concatenate?是一個(gè)帶有條件分支的函數(shù)并且有的分支中只用了兩個(gè)參數(shù)中的一個(gè),另一個(gè)參數(shù)就永遠(yuǎn)沒(méi)有必要被求值。
lambda或者高階函數(shù)是一種設(shè)計(jì)模式,是否適合應(yīng)該要看更大范圍的設(shè)計(jì)需要。
脫離了需求場(chǎng)景,返回lambda根本是脫褲子放屁。
map在python2返回list,在python3返回iterator.
如果想在python3得到可以反復(fù)重用的list,只要把iterator轉(zhuǎn)成list即可:
lst_result?=?list(map(func,?items))
Copyright ? 1999-2020, CSDN.NET, All Rights Reserved
惰性計(jì)算的序列
打開(kāi)APP
Python 的惰性求值與惰性序列 翻譯
2018-07-23 14:57:48
2點(diǎn)贊
東師小鎮(zhèn)
碼齡5年
關(guān)注
惰性求值
在編程語(yǔ)言理論中,惰性求值(英語(yǔ):Lazy Evaluation),又譯為惰性計(jì)算、懶惰求值,也稱為傳需求調(diào)用(call-by-need),是一個(gè)計(jì)算機(jī)編程中的一個(gè)概念,它的目的是要最小化計(jì)算機(jī)要做的工作。它有兩個(gè)相關(guān)而又有區(qū)別的含意,可以表示為“延遲求值”和“最小化求值”。
避免不必要的計(jì)算,帶來(lái)性能的提升(最小化求值)。
對(duì)于Python中的條件表達(dá)式 if x and y,在x為false的情況下y表達(dá)式的值將不再計(jì)算。而對(duì)于if x or y,當(dāng)x的值為true的時(shí)候?qū)⒅苯臃祷兀辉儆?jì)算y的值。因此編程中可以利用該特性,在 and邏輯中,將小概率發(fā)生的條件放在前面或者在or邏輯中,將大概率發(fā)生的時(shí)間放在前面,有助于性能的提升。
2. 節(jié)省空間,使得無(wú)線循環(huán)的數(shù)據(jù)結(jié)構(gòu)成為可能(延遲求值)。
延遲求值特別用于函數(shù)式編程語(yǔ)言中。在使用延遲求值的時(shí)候,表達(dá)式不在它被綁定到變量之后就立即求值,而是在該值被取用的時(shí)候求值。延遲求值的一個(gè)好處是能夠建立可計(jì)算的無(wú)限列表而沒(méi)有妨礙計(jì)算的無(wú)限循環(huán)或大小問(wèn)題。例如,可以建立生成無(wú)限斐波那契數(shù)列表的函數(shù)(經(jīng)常叫做“流”)。第n個(gè)斐波那契數(shù)的計(jì)算僅是從這個(gè)無(wú)限列表上提取出這個(gè)元素,它只要求計(jì)算這個(gè)列表的前n個(gè)成員。
惰性序列
Python的惰性序列多數(shù)指 iterator,其特點(diǎn)正如同上文所述,具有惰性計(jì)算特點(diǎn)的序列稱為惰性序列。
Python的iterator是一個(gè)惰性序列,意思是表達(dá)式和變量綁定后不會(huì)立即進(jìn)行求值,而是當(dāng)你用到其中某些元素的時(shí)候才去求某元素對(duì)的值。 惰性是指,你不主動(dòng)去遍歷它,就不會(huì)計(jì)算其中元素的值。
一句話理解:
迭代器的一個(gè)優(yōu)點(diǎn)就是它不要求你事先準(zhǔn)備好整個(gè)迭代過(guò)程中所有的元素。
迭代器僅僅在迭代至某個(gè)元素時(shí)才計(jì)算該元素,而在這之前或之后,元素可以不存在或者被銷毀。
這個(gè)特點(diǎn)使得它特別適合用于遍歷一些巨大的或是無(wú)限的集合,比如幾個(gè)G的文件,或是斐波那契數(shù)列等等。
新聞標(biāo)題:python惰性函數(shù) python惰性序列
地址分享:http://chinadenli.net/article34/hgpdse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、云服務(wù)器、網(wǎng)站導(dǎo)航、軟件開(kāi)發(fā)、定制開(kāi)發(fā)、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)