便利的響應(yīng)式網(wǎng)站建設(shè)百度競(jìng)價(jià)什么意思
人生苦短,我用python
python 安裝包+資料:點(diǎn)擊此處跳轉(zhuǎn)文末名片獲取
1.實(shí)現(xiàn)generator的兩種方式
python中的generator保存的是算法,
真正需要計(jì)算出值的時(shí)候才會(huì)去往下計(jì)算出值。
它是一種惰性計(jì)算(lazy evaluation)。
要?jiǎng)?chuàng)建一個(gè)generator有兩種方式。
第一種方法:
把一個(gè)列表生成式的[]改成(),
就創(chuàng)建了一個(gè)generator:
>>> L=[x * x for x in range(10)]
>>> L
[0,1,4,9,16,25,36,49,64,81]
>>> g = (x * x for x in range(10))#注意把[]改成()后,不是生成一個(gè)tuple,而是生成一個(gè)generator
>>> g
<generator object <genexpr> at 0x1022ef630>
第二種方式:
在函數(shù)中使用yield關(guān)鍵字,函數(shù)就變成了一個(gè)generator。
函數(shù)里有了yield后,執(zhí)行到y(tǒng)ield就會(huì)停住,
當(dāng)需要再往下算時(shí)才會(huì)再往下算。
所以生成器函數(shù)即使是有無限循環(huán)也沒關(guān)系,
它需要算到多少就會(huì)算多少,不需要就不往下算。
def fib():a,b = 0,1while True:yield aa, b = b, a + bf = fib()
print (f, next(f),next(f),next(f))
#<generator object fib at 0x7f89769d1fa0> 0 1 1
如上例,第一次輸出f,
它就是一個(gè)generator,
之后每次next,它就執(zhí)行到y(tǒng)ield a。
當(dāng)然其實(shí)平常很少用到next(),
我們直接用for循環(huán)就可以遍歷一個(gè)generator,
其實(shí)for循環(huán)的內(nèi)部實(shí)現(xiàn)就是不停調(diào)用next()。
生成器可以避免不必要的計(jì)算,
帶來性能上的提升;
而且會(huì)節(jié)約空間,
可以實(shí)現(xiàn)無限循環(huán)(無窮大的)的數(shù)據(jù)結(jié)構(gòu)。
2.可迭代對(duì)象(Iterable)和迭代器(Iterator)的概念
可以直接作用于for循環(huán)的對(duì)象統(tǒng)稱為可迭代對(duì)象:Iterable
。
包括集合數(shù)據(jù)類型(list、tuple、dict、set、str等)
和生成器(generator)。
可以使用isinstance()
判斷一個(gè)對(duì)象是否是Iterable對(duì)象。
>>>from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)),Iterable)
True
>>> isinstance(100,Iterable)
False
迭代器:Iterator。
它表示的是一個(gè)數(shù)據(jù)流,
Iterator對(duì)象可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)數(shù)據(jù),
直到?jīng)]有數(shù)據(jù)時(shí)拋出StopIteration錯(cuò)誤。
可以把這個(gè)數(shù)據(jù)流看做是一個(gè)有序序列,
但我們卻不能提前知道序列的長(zhǎng)度,
只能不斷通過next()
函數(shù)實(shí)現(xiàn)按需計(jì)算下一個(gè)數(shù)據(jù),
所以Iterator
的計(jì)算是惰性的,
只有在需要返回下一個(gè)數(shù)據(jù)時(shí)它才會(huì)計(jì)算。
Iterator
甚至可以表示一個(gè)無限大的數(shù)據(jù)流,
例如全體自然數(shù)。
而使用list
是永遠(yuǎn)不可能存儲(chǔ)全體自然數(shù)的。
生成器(generator)
都是Iterator對(duì)象,
但list、dict、str
雖然是Iterable
,
卻不是Iterator
。
把list、dict、str
等Iterable
變成Iterator
可以使用iter()
函數(shù):
>>> isinstance(iter([]),Iterator)
True
>>> isinstance( iter('abc'),Iterator)
True
Python的for循環(huán)本質(zhì)上就是通過不斷調(diào)用next()
函數(shù)實(shí)現(xiàn)的,
例如:
for x in [1,2,3,4,5]:pass
實(shí)際上完全等價(jià)于:
#首先獲得Iterator對(duì)象:
it= iter([1,2,3,4,5])#循環(huán):
while True:try:#獲得下一個(gè)值:x = next(it)except StopIteration:#遇到StopIteration就退出循環(huán)break
3.itertools模塊
python的內(nèi)置模塊itertools
提供了用于操作迭代對(duì)象的函數(shù),
非常方便實(shí)用。
舉一個(gè)例子:
islice(iterable, [start, ] stop [, step]):
創(chuàng)建一個(gè)迭代器,
生成項(xiàng)的方式類似于切片返回值:
iterable[start : stop : step],
將跳過前start個(gè)項(xiàng),迭代在stop所指定的位置停止
step指定用于跳過項(xiàng)的步幅。
與切片不同,
負(fù)值不會(huì)用于任何start
,stop
和step
,
如果省略了start
,迭代將從0開始,
如果省略了step
,步幅將采用1.
from itertools import islicedef fib():a, b = 0,1while True:yield aa, b = b,a + bf = fib()
print (list(islice(f,10)))#[0,1,1,2,3,5,8,13,21,34]python學(xué)習(xí)交流扣扣qun:903971231