1. 程式人生 > 實用技巧 >python迭代器模組itertools常用方法

python迭代器模組itertools常用方法

itertools是python中內建的一種高效的生成各種迭代器或者是類的模組,這些函式的返回值為一個迭代器,經常被用在for迴圈中,當然,也可直接使用next()方法取值,今天就來說說itertools中的常用方法.

itertools按照迭代器的功能可分為三類:

  • 無限迭代器: 生成一個無限序列,比如自然數序列 1, 2, 3, 4, …
  • 有限迭代器: 接收一個或多個序列(sequence)作為引數,進行組合、分組和過濾等;
  • 組合迭代器: 序列的排列、組合,求序列的笛卡兒積等

無限迭代器

itertools.count(start=0, step=1)

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
itertools.count(start=0, step=1)
#建立一個迭代器,生成從n開始的連續整數,如果忽略n,則從0開始計算(注意:此迭代器不支援長整數),如果超出了sys.maxint,計數器將溢位並繼續從-sys.maxint-1開始計算
#start: 起始值,預設為0,
#step: 步長,預設為1

import itertools
a = itertools.count()
for x in a:
if x > 5:
break
print(x)
#輸出:
1
2
3
4
5
6

b = itertools.count(2,3)
for x in b:
if x > 10:
break
print(x)
#輸出
2
5
8

itertools.cycle(iterable)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
itertools.cycle(iterable)
#建立一個迭代器,對iterable中的元素反覆執行迴圈操作,內部會生成iterable中的元素的一個副本,此副本用於返回迴圈中的重複項
#iterable: 可迭代物件,可以為一個列表、字串、元組等

import itertools
a = ['a','b','c']
i = 0
for x in itertools.cycle(a):
i = i +1
if i > 5:
break
print(i,x)

#輸出
1,'a'
2,'b'
3,'c'
4,'a'
5,'b'

itertools.repeat(object[, times])

1
2
3
4
5
6
7
8
9
10
11
12
13
itertools.repeat(object[, times])
#建立一個迭代器,重複生成object,times(如果已提供)指定重複計數,如果未提供times,將無止盡返回該物件
#object: 需要重複的物件,物件是個整體
#times: 重複次數

import itertools
for x in itertools.repeat([1,2,3],3):
print(x)

#輸出
[1,2,3]
[1,2,3]
[1,2,3]

有限迭代器

itertools.chain(iterable1, iterable2, …)

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
itertools.chain(iterable1, iterable2, ...)
#將多個迭代器作為引數, 但只返回單個迭代器, 它產生所有引數迭代器的內容, 就好像他們是來自於一個單一的序列
#引數為多個可迭代物件,就好像被鏈條銜接起來了一樣

import itertools
for x in itertools.chain([1,2,3],'abc'):
print(x)

#輸出
1
2
3
'a'
'b'
'c'

for x in itertools.chain([1,2,3],['a','b','c']):
print(x)
#輸出
1
2
3
'a'
'b'
'c'

itertools.chain.from_iterable(iterable)

1
2
3
4
5
6
7
8
9
10
11
12
itertools.chain.from_iterable(iterable)
#接收一個可迭代物件作為引數,返回一個迭代器

from itertools import chain
a = [['first','second','thrid'],['a','b','c']]
b = [[1,2,3],[4,5,6]]
for x in range(len(a)):
list(chain.from_iterable(zip(a[x],b[x])))

#輸出
['first', 1, 'second', 2, 'thrid', 3]
['a', 4, 'b', 5, 'c', 6]

itertools.compress(data, selectors)

1
2
3
4
5
6
7
8
9
10
11
12
13
itertools.compress(data, selectors)
#可用於對資料進行篩選,當 selectors 的某個元素為 true 時,則保留 data 對應位置的元素,否則去除
#data: 待篩選資料
#selectors: 當為真時,保留data對應位的資料,為假或為空時則去除

from itertools import compress
for x in compress(['a','b','c','d'],[1,0,2]):
print(x)

#輸出
'a'
'c'
# 2 也為真,'d'對應值為空算假

itertools.dropwhile(predicate, iterable)

1
2
3
4
5
6
7
8
9
10
itertools.dropwhile(predicate, iterable)
#建立一個迭代器,只要函式predicate(item)為True,就丟棄iterable中的項,如果predicate返回False,就會生成iterable中的項和所有後續項,即第一個不滿足條件的項及它後面所有的項都返回
#predicate: 函式
#iterable: 可迭代物件

from itertools import dropwhile
list(dropwhile(lambda x: x < 5, [1, 3, 6, 2, 1]))
#輸出:
[6,2,1]
#從6開始不符合x < 5 條件,所以6及6後面所有的項都需要返回

itertools.takewhile(predicate, iterable)

1
2
3
4
5
6
7
itertools.takewhile(predicate, iterable)
#建立一個迭代器,如果predicate返回False,立即停止迭代

from itertools import takewhile
list(takewhile(lambda x: x < 5, [1, 3, 6, 2, 1]))
#輸出
[1,3]

itertools.ifilter(predicate, iterable)

1
2
3
4
5
6
7
8
9
itertools.ifilter(predicate, iterable)
#建立一個迭代器,僅生成iterable中predicate(item)為True的項,如果predicate為None,將返回iterable中所有計算為True的項
#predicate: 函式
#iterable: 可迭代物件

from itertools import ifilter
list(ifilter(lambda x: x < 5, [1, 3, 6, 2, 1]))
#輸出:
[1,3,2,1]

itertools.ifilterfalse(predicate, iterable)

1
2
3
4
5
6
7
8
9
itertools.ifilterfalse(predicate, iterable)
#建立一個迭代器,僅生成iterable中predicate(item)為False的項,如果predicate為None,將返回iterable中所有計算False的項,該函式正好跟ifilter相反
#predicate: 函式
#iterable: 可迭代物件

from itertools import ifilterfalse
list(ifilterfalse(lambda x: x < 5, [1, 3, 6, 2, 1]))
#輸出:
[6]

itertools.groupby(iterable[, key])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
itertools.groupby(iterable[, key])
#返回一個產生按照key進行分組後的值集合的迭代器
#iterable:可迭代物件
#key: 一個函式,該函式的返回值做為分組的標準

from itertools import groupby
a = ['aa', 'ab', 'abc', 'bcd', 'abcde']
for i, k in groupby(a, len):
print (i, list(k))

#輸出
2,['aa', 'ab']
3,['abc', 'bcd']
5,['abcde']

itertools.islice(iterable, stop)

1
2
3
4
5
6
7
8
9
10
11
12
itertools.islice(iterable,[start], stop,[step])
#iterable 是可迭代物件,start 是開始索引,預設為0,stop 是結束索引,step 是步長,預設為1,start 和 step 可選

from itertools import islice,count
list(islice([10, 6, 2, 8, 1, 3, 9], 5))
#輸出
[[10, 6, 2, 8, 1]

list(islice(count(), 3, 10 ,2))
#輸出
[3,5,7,9]
#這裡的count()為文章第一個函式,用來產生無限序列

itertools.imap(func, iter1, iter2, iter3, …)

1
2
3
4
5
6
7
8
9
imap(func, iter1, iter2, iter3, ...)
#返回一個迭代器, 它是呼叫了一個其值在輸入迭代器上的函式, 返回結果. 它類似於內建函式 map() , 只是前者在任意輸入迭代器結束後就停止(而不是插入None值來補全所有的輸入)
#注意: 該函式在python3.x中已不存在,可直接使用map

from itertools import imap
list(imap(pow, [2, 3, 10], [4, 2, 3]))
#輸出
[16, 9, 1000]
#pow函式 求指數

itertools.izip(*iterables)

1
2
3
4
5
6
7
8
9
10
11
12
itertools.izip(*iterables)
#用於將多個可迭代物件對應位置的元素作為一個元組,將所有元組『組成』一個迭代器,並返回
#注意: 該函式在python3.x中已不存在,可直接使用zip

from itertools import izip
for item in izip([1, 2, 3], ['a', 'b', 'c', 'd', 'e']):
print(item)

#輸出
(1, 'a')
(2, 'b')
(3, 'c')

itertools.izip_longest(*iterables, [fillvalue=None])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
itertools.izip_longest(*iterables,[fillvalue=None])
#izip_longest 跟 izip 類似,但迭代過程會持續到所有可迭代物件的元素都被迭代完
#注意: 該函式在python3.x中已不存在

from itertools import izip_longest
for item in izip_longest([1, 2, 3], ['a', 'b', 'c', 'd', 'e'],fillvalue='-'):
print(item)

#輸出
(1, 'a')
(2, 'b')
(3, 'c')
('-','d')
('-','e')

組合迭代器

itertools.product(*iterables[, repeat])

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
itertools.product(*iterables[, repeat])
#建立一個迭代器,生成表示item1,item2等中的專案的笛卡爾積的元組,repeat是一個關鍵字引數,指定重複生成序列的次數。
# 用來產生笛卡爾積

import itertools
a = (1, 2, 3)
b = ('A', 'B', 'C')
c = itertools.product(a,b)
for elem in c:
print(elem)

#輸出
(1, 'A')
(1, 'B')
(1, 'C')
(2, 'A')
(2, 'B')
(2, 'C')
(3, 'A')
(3, 'B')
(3, 'C')

list(product((0,1), (0,1), (0,1)))
#輸出
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]

list(product('ABC', repeat=2))
#輸出
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C')]

itertools.permutations(iterable[, r])

1
2
3
4
5
6
7
itertools.permutations(iterable[, r])
#建立一個迭代器,返回iterable中所有長度為r的專案序列,如果省略了r,那麼序列的長度與iterable中的專案數量相同: 返回p中任意取r個元素做排列的元組的迭代器

from itertools import permutations
list(permutations('ABC', 2))
#輸出
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

itertools.combinations(iterable, r)

1
2
3
4
5
6
7
itertools.combinations(iterable, r)
#建立一個迭代器,返回iterable中所有長度為r的子序列,返回的子序列中的項按輸入iterable中的順序排序 (不帶重複)

from itertools import combinations
list(combinations('ABC', 2))
#輸出
[('A', 'B'), ('A', 'C'), ('B', 'C')]

itertools.combinations_with_replacement(iterable, r)

1
2
3
4
5
6
7
itertools.combinations_with_replacement(iterable, r)
#建立一個迭代器,返回iterable中所有長度為r的子序列,返回的子序列中的項按輸入iterable中的順序排序 (帶重複)

from itertools import combinations_with_replacement
list(combinations_with_replacement('ABC', 2))
#輸出
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]