摘要:借鑒了中的某些迭代器的構(gòu)造方法,并在中實(shí)現(xiàn)該模塊是通過實(shí)現(xiàn),源代碼。
項(xiàng)目地址:https://git.io/pytips
0x01 介紹了迭代器的概念,即定義了 __iter__() 和 __next__() 方法的對(duì)象,或者通過 yield 簡化定義的“可迭代對(duì)象”,而在一些函數(shù)式編程語言(見 0x02 Python 中的函數(shù)式編程)中,類似的迭代器常被用于產(chǎn)生特定格式的列表(或序列),這時(shí)的迭代器更像是一種數(shù)據(jù)結(jié)構(gòu)而非函數(shù)(當(dāng)然在一些函數(shù)式編程語言中,這兩者并無本質(zhì)差異)。Python 借鑒了 APL, Haskell, and SML 中的某些迭代器的構(gòu)造方法,并在 itertools 中實(shí)現(xiàn)(該模塊是通過 C 實(shí)現(xiàn),源代碼:/Modules/itertoolsmodule.c)。
itertools 模塊提供了如下三類迭代器構(gòu)建工具:
無限迭代
整合兩序列迭代
組合生成器
1. 無限迭代所謂無限(infinite)是指如果你通過 for...in... 的語法對(duì)其進(jìn)行迭代,將陷入無限循環(huán),包括:
count(start, [step])
cycle(p)
repeat(elem [,n])
從名字大概可以猜出它們的用法,既然說是無限迭代,我們自然不會(huì)想要將其所有元素依次迭代取出,而通常是結(jié)合 map/zip 等方法,將其作為一個(gè)取之不盡的數(shù)據(jù)倉庫,與有限長度的可迭代對(duì)象進(jìn)行組合操作:
from itertools import cycle, count, repeat print(count.__doc__)
count(start=0, step=1) --> count object Return a count object whose .__next__() method returns consecutive values. Equivalent to: def count(firstval=0, step=1): x = firstval while 1: yield x x += step
counter = count() print(next(counter)) print(next(counter)) print(list(map(lambda x, y: x+y, range(10), counter))) odd_counter = map(lambda x: "Odd#{}".format(x), count(1, 2)) print(next(odd_counter)) print(next(odd_counter))
0 1 [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] Odd#1 Odd#3
print(cycle.__doc__)
cycle(iterable) --> cycle object Return elements from the iterable until it is exhausted. Then repeat the sequence indefinitely.
cyc = cycle(range(5)) print(list(zip(range(6), cyc))) print(next(cyc)) print(next(cyc))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 0)] 1 2
print(repeat.__doc__)
repeat(object [,times]) -> create an iterator which returns the object for the specified number of times. If not specified, returns the object endlessly.
print(list(repeat("Py", 3))) rep = repeat("p") print(list(zip(rep, "y"*3)))
["Py", "Py", "Py"] [("p", "y"), ("p", "y"), ("p", "y")]2. 整合兩序列迭代
所謂整合兩序列,是指以兩個(gè)有限序列為輸入,將其整合操作之后返回為一個(gè)迭代器,最為常見的 zip 函數(shù)就屬于這一類別,只不過 zip 是內(nèi)置函數(shù)。這一類別完整的方法包括:
accumulate()
chain()/chain.from_iterable()
compress()
dropwhile()/filterfalse()/takewhile()
groupby()
islice()
starmap()
tee()
zip_longest()
這里就不對(duì)所有的方法一一舉例說明了,如果想要知道某個(gè)方法的用法,基本通過 print(method.__doc__) 就可以了解,畢竟 itertools 模塊只是提供了一種快捷方式,并沒有隱含什么深?yuàn)W的算法。這里只對(duì)下面幾個(gè)我覺得比較有趣的方法進(jìn)行舉例說明。
from itertools import cycle, compress, islice, takewhile, count # 這三個(gè)方法(如果使用恰當(dāng))可以限定無限迭代 # print(compress.__doc__) print(list(compress(cycle("PY"), [1, 0, 1, 0]))) # 像操作列表 l[start:stop:step] 一樣操作其它序列 # print(islice.__doc__) print(list(islice(cycle("PY"), 0, 2))) # 限制版的 filter # print(takewhile.__doc__) print(list(takewhile(lambda x: x < 5, count())))
["P", "P"] ["P", "Y"] [0, 1, 2, 3, 4]
from itertools import groupby from operator import itemgetter print(groupby.__doc__) for k, g in groupby("AABBC"): print(k, list(g)) db = [dict(name="python", script=True), dict(name="c", script=False), dict(name="c++", script=False), dict(name="ruby", script=True)] keyfunc = itemgetter("script") db2 = sorted(db, key=keyfunc) # sorted by `script" for isScript, langs in groupby(db2, keyfunc): print(", ".join(map(itemgetter("name"), langs)))
groupby(iterable[, keyfunc]) -> create an iterator which returns (key, sub-iterator) grouped by each value of key(value). A ["A", "A"] B ["B", "B"] C ["C"] c, c++ python, ruby
from itertools import zip_longest # 內(nèi)置函數(shù) zip 以較短序列為基準(zhǔn)進(jìn)行合并, # zip_longest 則以最長序列為基準(zhǔn),并提供補(bǔ)足參數(shù) fillvalue # Python 2.7 中名為 izip_longest print(list(zip_longest("ABCD", "123", fillvalue=0)))
[("A", "1"), ("B", "2"), ("C", "3"), ("D", 0)]3. 組合生成器
關(guān)于生成器的排列組合:
product(*iterables, repeat=1):兩輸入序列的笛卡爾乘積
permutations(iterable, r=None):對(duì)輸入序列的完全排列組合
combinations(iterable, r):有序版的排列組合
combinations_with_replacement(iterable, r):有序版的笛卡爾乘積
from itertools import product, permutations, combinations, combinations_with_replacement print(list(product(range(2), range(2)))) print(list(product("AB", repeat=2)))
[(0, 0), (0, 1), (1, 0), (1, 1)] [("A", "A"), ("A", "B"), ("B", "A"), ("B", "B")]
print(list(combinations_with_replacement("AB", 2)))
[("A", "A"), ("A", "B"), ("B", "B")]
# 賽馬問題:4匹馬前2名的排列組合(A^4_2) print(list(permutations("ABCDE", 2)))
[("A", "B"), ("A", "C"), ("A", "D"), ("A", "E"), ("B", "A"), ("B", "C"), ("B", "D"), ("B", "E"), ("C", "A"), ("C", "B"), ("C", "D"), ("C", "E"), ("D", "A"), ("D", "B"), ("D", "C"), ("D", "E"), ("E", "A"), ("E", "B"), ("E", "C"), ("E", "D")]
# 彩球問題:4種顏色的球任意抽出2個(gè)的顏色組合(C^4_2) print(list(combinations("ABCD", 2)))
[("A", "B"), ("A", "C"), ("A", "D"), ("B", "C"), ("B", "D"), ("C", "D")]總結(jié)
迭代器工具在產(chǎn)生數(shù)據(jù)的時(shí)候?qū)?huì)顯得非常便捷、高效,掌握了這些基本的方法之后,通過簡單的組合就可以獲得更多迭代器工具。
歡迎關(guān)注公眾號(hào) PyHub 每日推送
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/45422.html
摘要:項(xiàng)目地址迭代器與生成器迭代器與生成器是中比較常用又很容易混淆的兩個(gè)概念,今天就把它們梳理一遍,并舉一些常用的例子。生成器前面說到創(chuàng)建迭代器有種方法,其中第三種就是生成器。 項(xiàng)目地址:https://git.io/pytips 迭代器與生成器 迭代器(iterator)與生成器(generator)是 Python 中比較常用又很容易混淆的兩個(gè)概念,今天就把它們梳理一遍,并舉一些常用的例...
摘要:項(xiàng)目地址引入了語句與上下文管理器類型,其主要作用包括保存重置各種全局狀態(tài),鎖住或解鎖資源,關(guān)閉打開的文件等。了解了語句的執(zhí)行過程,我們可以編寫自己的上下文管理器。生成器的寫法更簡潔,適合快速生成一個(gè)簡單的上下文管理器。 項(xiàng)目地址:https://git.io/pytips Python 2.5 引入了 with 語句(PEP 343)與上下文管理器類型(Context Manager ...
摘要:項(xiàng)目地址我之前翻譯了協(xié)程原理這篇文章之后嘗試用了模式下的協(xié)程進(jìn)行異步開發(fā),確實(shí)感受到協(xié)程所帶來的好處至少是語法上的。 項(xiàng)目地址:https://git.io/pytips 我之前翻譯了Python 3.5 協(xié)程原理這篇文章之后嘗試用了 Tornado + Motor 模式下的協(xié)程進(jìn)行異步開發(fā),確實(shí)感受到協(xié)程所帶來的好處(至少是語法上的:D)。至于協(xié)程的 async/await 語法是如...
摘要:項(xiàng)目地址提供兩種內(nèi)置排序方法,一個(gè)是只針對(duì)的原地排序方法,另一個(gè)是針對(duì)所有可迭代對(duì)象的非原地排序方法。 項(xiàng)目地址:https://git.io/pytips Python 提供兩種內(nèi)置排序方法,一個(gè)是只針對(duì) List 的原地(in-place)排序方法 list.sort(),另一個(gè)是針對(duì)所有可迭代對(duì)象的非原地排序方法 sorted()。 所謂原地排序是指會(huì)立即改變被排序的列表對(duì)象,就...
摘要:項(xiàng)目地址列表推導(dǎo)中提到的方法可以通過簡化的語法快速構(gòu)建我們需要的列表或其它可迭代對(duì)象,與它們功能相似的,還提供列表推導(dǎo)的語法。 項(xiàng)目地址:https://git.io/pytips 0x03 - Python 列表推導(dǎo) 0x02 中提到的 map/filter 方法可以通過簡化的語法快速構(gòu)建我們需要的列表(或其它可迭代對(duì)象),與它們功能相似的,Python 還提供列表推導(dǎo)(List C...
閱讀 2586·2021-10-25 09:45
閱讀 1246·2021-10-14 09:43
閱讀 2304·2021-09-22 15:23
閱讀 1529·2021-09-22 14:58
閱讀 1939·2019-08-30 15:54
閱讀 3547·2019-08-30 13:00
閱讀 1361·2019-08-29 18:44
閱讀 1578·2019-08-29 16:59