Python的內(nèi)建模塊itertools
提供了非常有用的用于操作迭代對象的函數(shù)。
首先罪塔,我們看看itertools
提供的幾個“無限”迭代器:
>>> import itertools
>>> natuals = itertools.count(1)
>>> for n in natuals:
... print(n)
...
1
2
3
...
因為count()
會創(chuàng)建一個無限的迭代器角骤,所以上述代碼會打印出自然數(shù)序列隅忿,根本停不下來,只能按Ctrl+C
退出邦尊。
cycle()
會把傳入的一個序列無限重復下去:
>>> import itertools
>>> cs = itertools.cycle('ABC') # 注意字符串也是序列的一種
>>> for c in cs:
... print(c)
...
'A'
'B'
'C'
'A'
'B'
'C'
...
同樣停不下來背桐。
repeat()
負責把一個元素無限重復下去,不過如果提供第二個參數(shù)就可以限定重復次數(shù):
>>> ns = itertools.repeat('A', 3)
>>> for n in ns:
... print(n)
...
A
A
A
無限序列只有在for
迭代時才會無限地迭代下去蝉揍,如果只是創(chuàng)建了一個迭代對象链峭,它不會事先把無限個元素生成出來,事實上也不可能在內(nèi)存中創(chuàng)建無限多個元素又沾。
無限序列雖然可以無限迭代下去弊仪,但是通常我們會通過takewhile()
等函數(shù)根據(jù)條件判斷來截取出一個有限的序列:
>>> natuals = itertools.count(1)
>>> ns = itertools.takewhile(lambda x: x <= 10, natuals)
>>> list(ns)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
itertools
提供的幾個迭代器操作函數(shù)更加有用:
chain()
chain()
可以把一組迭代對象串聯(lián)起來熙卡,形成一個更大的迭代器:
>>> for c in itertools.chain('ABC', 'XYZ'):
... print(c)
# 迭代效果:'A' 'B' 'C' 'X' 'Y' 'Z'
groupby()
groupby()
把迭代器中相鄰的重復元素挑出來放在一起:
>>> for key, group in itertools.groupby('AAABBBCCAAA'):
... print(key, list(group))
...
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
實際上挑選規(guī)則是通過函數(shù)完成的,只要作用于函數(shù)的兩個元素返回的值相等励饵,這兩個元素就被認為是在一組的驳癌,而函數(shù)返回值作為組的key。如果我們要忽略大小寫分組曲横,就可以讓元素'A'
和'a'
都返回相同的key:
>>> for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
... print(key, list(group))
...
A ['A', 'a', 'a']
B ['B', 'B', 'b']
C ['c', 'C']
A ['A', 'A', 'a']
練習
計算圓周率可以根據(jù)公式:
利用Python提供的itertools模塊喂柒,我們來計算這個序列的前N項和:
import itertools
def pi(N):
' 計算pi的值 '
# step 1: 創(chuàng)建一個奇數(shù)序列: 1, 3, 5, 7, 9, ...
odds = itertools.count(1, 2)
# step 2: 取該序列的前N項: 1, 3, 5, 7, 9, ..., 2*N-1.
odd_iter = itertools.takewhile(lambda x: x < 2*N, odds)
# step 3: 添加正負符號并用4除: 4/1, -4/3, 4/5, -4/7, 4/9, ...
lst = [4.0/i*(-1)**(i//2) for i in odd_iter]
# step 4: 求和:
return sum(lst)
print(pi(1000000))
小結(jié)
itertools模塊提供的全部是處理迭代功能的函數(shù),它們的返回值不是list禾嫉,而是Iterator灾杰,只有用for循環(huán)迭代的時候才真正計算。