1. 程式人生 > >python標準庫----itertools

python標準庫----itertools

python標準庫系列教程(一)——itertools

01

宣告

functools, itertools, operator是Python標準庫為我們提供的支援函數語言程式設計的三大模組,合理的使用這三個模組,我們可以寫出更加簡潔可讀的Pythonic程式碼,本次的系列文章將介紹並使用這些python自帶的標準模組,系列文章分篇連載,此為第一篇,有興趣的小夥伴後面記得關注學習哦!

 

高效的itertools模組

我們知道,迭代器的特點是:惰性求值(Lazy evaluation),即只有當迭代至某個值時,它才會被計算,這個特點使得迭代器特別適合於遍歷大檔案或無限集合等,因為我們不用一次性將它們儲存在記憶體中。

Python 內建的 itertools 模組包含了一系列用來產生不同型別迭代器的函式或類,這些函式的返回都是一個迭代器,我們可以通過 for 迴圈來遍歷取值,也可以使用 next() 來取值。

itertools 模組提供的迭代器函式有以下幾種型別:

1,無限迭代器:生成一個無限序列,比如自然數序列 1, 2, 3, 4, ...

2,有限迭代器:接收一個或多個序列(sequence)作為引數,進行組合、分組和過濾等;

3,組合生成器:序列的排列、組合,求序列的笛卡兒積等;

目錄

一 無限迭代器

   1.1 count

   1.2 cycle

   1.3 repeat

二 有限迭代器

   2.1 chain

   2.2 compress

   2.3 dropwhile

   2.4 groupby

   2.5 ifilter

   2.6 ifilterfalse

   2.7 islice

   2.8 imap

   2.9 tee

   2.10 takewhile

   2.11 izip

   2.12 izip-longest

三 組合生成器

   3.1 product

   3.2 permutations

   3.3 combinations

   3.4 combinations-with-replacement

四 總結

 

1,無限迭代器

itertools 模組提供了三個函式(事實上,它們是類)用於生成一個無限序列迭代器:

1,

count(firstval=0, step=1)建立一個從 firstval (預設值為 0) 開始,以 step (預設值為 1) 為步長的的無限整數迭代器

  • cycle(iterable)對 iterable 中的元素反覆執行迴圈,返回迭代器

  • repeat(object [,times]反覆生成 object,如果給定 times,則重複次數為 times,否則為無限

下面,讓我們看看一些例子。

 

無限迭代器

1.1 count

count() 接收兩個引數,第一個引數指定開始值,預設為 0,第二個引數指定步長,預設為 1:

>>> import itertools
>>>
>>> nums = itertools.count()
>>> for i in nums:
...     if i > 6:
...         break
...     print i
...
0
1
2
3
4
5
6
>>> nums = itertools.count(10, 2)    # 指定開始值和步長
>>> for i in nums:
...     if i > 20:
...         break
...     print i
...
10
12
14
16
18
20

無限迭代器

1.2 cycle

cycle() 用於對 iterable 中的元素反覆執行迴圈:

>>> import itertools
>>>
>>> cycle_strings = itertools.cycle('ABC')
>>> i = 1
>>> for string in cycle_strings:
...     if i == 10:
...         break
...     print i, string
...     i += 1
...
1 A
2 B
3 C
4 A
5 B
6 C
7 A
8 B
9 C

 

無限迭代器

1.3 repeat

repeat() 用於反覆生成一個 object:

>>> import itertools
>>>
>>> for item in itertools.repeat('hello world', 3):
...     print item
...
hello world
hello world
hello world
>>>
>>> for item in itertools.repeat([1, 2, 3, 4], 3):
...     print item
...
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]

2,有限迭代器

itertools 模組提供了多個函式(類),接收一個或多個迭代物件作為引數,對它們進行組合、分組和過濾等:

chain()

compress()

dropwhile()

groupby()

ifilter()

ifilterfalse()

islice()

imap()

starmap()

tee()

takewhile()

izip()

izip_longest()

有限迭代器

2.1 chain

chain 的使用形式如下:

chain(iterable1, iterable2, iterable3, ...)

chain 接收多個可迭代物件作為引數,將它們『連線』起來,作為一個新的迭代器返回。

>>> from itertools import chain
>>>
>>> for item in chain([1, 2, 3], ['a', 'b', 'c']):
...     print item
...
1
2
3
a
b
c

chain 還有一個常見的用法:

chain.from_iterable(iterable)

接收一個可迭代物件作為引數,返回一個迭代器:

>>> from itertools import chain
>>>
>>> string = chain.from_iterable('ABCD')
>>> string.next()
'A'

有限迭代器

2.2 compress

compress 的使用形式如下:

compress(data, selectors)

compress 可用於對資料進行篩選,當 selectors 的某個元素為 true 時,則保留 data 對應位置的元素,否則去除:

>>> from itertools import compress
>>>
>>> list(compress('ABCDEF', [1, 1, 0, 1, 0, 1]))
['A', 'B', 'D', 'F']
>>> list(compress('ABCDEF', [1, 1, 0, 1]))
['A', 'B', 'D']
>>> list(compress('ABCDEF', [True, False, True]))
['A', 'C']

有限迭代器

2.3 dropwhile

dropwhile 的使用形式如下:

dropwhile(predicate, iterable)

其中,predicate 是函式,iterable 是可迭代物件。對於 iterable 中的元素,如果 predicate(item) 為 true,則丟棄該元素,否則返回該項及所有後續項。

>>> from itertools import dropwhile
>>>
>>> list(dropwhile(lambda x: x < 5, [1, 3, 6, 2, 1]))
[6, 2, 1]
>>>
>>> list(dropwhile(lambda x: x > 3, [2, 1, 6, 5, 4]))
[2, 1, 6, 5, 4]

 

有限迭代器

2.4 groupby

groupby 用於對序列進行分組,它的使用形式如下:

groupby(iterable[, keyfunc])

其中,iterable 是一個可迭代物件,keyfunc 是分組函式,用於對 iterable 的連續項進行分組,如果不指定,則預設對 iterable 中的連續相同項進行分組,返回一個 (key, sub-iterator) 的迭代器。

>>> from itertools import groupby
>>>
>>> for key, value_iter in groupby('aaabbbaaccd'):
...     print key, ':', list(value_iter)
...
a : ['a', 'a', 'a']
b : ['b', 'b', 'b']
a : ['a', 'a']
c : ['c', 'c']
d : ['d']
>>>
>>> data = ['a', 'bb', 'ccc', 'dd', 'eee', 'f']
>>> for key, value_iter in groupby(data, len):    # 使用 len 函式作為分組函式
...     print key, ':', list(value_iter)
...
1 : ['a']
2 : ['bb']
3 : ['ccc']
2 : ['dd']
3 : ['eee']
1 : ['f']
>>>
>>> data = ['a', 'bb', 'cc', 'ddd', 'eee', 'f']
>>> for key, value_iter in groupby(data, len):
...     print key, ':', list(value_iter)
...
1 : ['a']
2 : ['bb', 'cc']
3 : ['ddd', 'eee']
1 : ['f']

有限迭代器

2.5 ifilter

ifilter 的使用形式如下:

ifilter(function or None, sequence)

將 iterable 中 function(item) 為 True 的元素組成一個迭代器返回,如果 function 是 None,則返回 iterable 中所有計算為 True 的項。

>>> from itertools import ifilter
>>>
>>> list(ifilter(lambda x: x < 6, range(10)))
[0, 1, 2, 3, 4, 5]
>>>
>>> list(ifilter(None, [0, 1, 2, 0, 3, 4]))
[1, 2, 3, 4]

有限迭代器

2.6 ifilterfalse

ifilterfalse 的使用形式和 ifilter 類似,它將 iterable 中 function(item) 為 False 的元素組成一個迭代器返回,如果 function 是 None,則返回 iterable 中所有計算為 False 的項。

>>> from itertools import ifilterfalse
>>>
>>> list(ifilterfalse(lambda x: x < 6, range(10)))
[6, 7, 8, 9]
>>>
>>> list(ifilter(None, [0, 1, 2, 0, 3, 4]))
[0, 0]

有限迭代器

2.7 islice

islice 是切片選擇,它的使用形式如下:

islice(iterable, [start,] stop [, step])

其中,iterable 是可迭代物件,start 是開始索引,stop 是結束索引,step 是步長,start 和 step 可選。

>>> from itertools import count, islice
>>>
>>> list(islice([10, 6, 2, 8, 1, 3, 9], 5))
[10, 6, 2, 8, 1]
>>>
>>> list(islice(count(), 6))
[0, 1, 2, 3, 4, 5]
>>>
>>> list(islice(count(), 3, 10))
[3, 4, 5, 6, 7, 8, 9]
>>> list(islice(count(), 3, 10 ,2))
[3, 5, 7, 9]

有限迭代器

2.8 imap

imap 類似 map 操作,它的使用形式如下:

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

imap 返回一個迭代器,元素為 func(i1, i2, i3, ...)i1i2 等分別來源於 iter, iter2

>>> from itertools import imap
>>>
>>> imap(str, [1, 2, 3, 4])
<itertools.imap object at 0x10556d050>
>>>
>>> list(imap(str, [1, 2, 3, 4]))
['1', '2', '3', '4']
>>>
>>> list(imap(pow, [2, 3, 10], [4, 2, 3]))
[16, 9, 1000]

有限迭代器

2.9 tee

tee 的使用形式如下:

tee(iterable [,n])

tee 用於從 iterable 建立 n 個獨立的迭代器,以元組的形式返回,n 的預設值是 2。

>>> from itertools import tee
>>>
>>> tee('abcd')   # n 預設為 2,建立兩個獨立的迭代器
(<itertools.tee object at 0x1049957e8>, <itertools.tee object at 0x104995878>)
>>>
>>> iter1, iter2 = tee('abcde')
>>> list(iter1)
['a', 'b', 'c', 'd', 'e']
>>> list(iter2)
['a', 'b', 'c', 'd', 'e']
>>>
>>> tee('abc', 3)  # 建立三個獨立的迭代器
(<itertools.tee object at 0x104995998>, <itertools.tee object at 0x1049959e0>, <itertools.tee object at 0x104995a28>)

有限迭代器

2.10 takewhile

takewhile 的使用形式如下:

takewhile(predicate, iterable)

其中,predicate 是函式,iterable 是可迭代物件。對於 iterable 中的元素,如果 predicate(item) 為 true,則保留該元素,只要 predicate(item) 為 false,則立即停止迭代。

>>> from itertools import takewhile
>>>
>>> list(takewhile(lambda x: x < 5, [1, 3, 6, 2, 1]))
[1, 3]
>>> list(takewhile(lambda x: x > 3, [2, 1, 6, 5, 4]))
[]

有限迭代器

2.11 izip

izip 用於將多個可迭代物件對應位置的元素作為一個元組,將所有元組『組成』一個迭代器,並返回。它的使用形式如下:

izip(iter1, iter2, ..., iterN)

如果某個可迭代物件不再生成值,則迭代停止。

>>> from itertools import izip
>>> 
>>> for item in izip('ABCD', 'xy'):
...     print item
...
('A', 'x')
('B', 'y')
>>> for item in izip([1, 2, 3], ['a', 'b', 'c', 'd', 'e']):
...     print item
...
(1, 'a')
(2, 'b')
(3, 'c')

有限迭代器

2.12 izip-longest

izip_longestizip 類似,但迭代過程會持續到所有可迭代物件的元素都被迭代完。它的形式如下:

izip_longest(iter1, iter2, ..., iterN, [fillvalue=None])

如果有指定 fillvalue,則會用其填充缺失的值,否則為 None。

>>> from itertools import izip_longest
>>>
>>> for item in izip_longest('ABCD', 'xy'):
...     print item
...
('A', 'x')
('B', 'y')
('C', None)
('D', None)
>>>
>>> for item in izip_longest('ABCD', 'xy', fillvalue='-'):
...     print item
...
('A', 'x')
('B', 'y')
('C', '-')
('D', '-')

3, 組合生成器

itertools 模組還提供了多個組合生成器函式,用於求序列的排列、組合等:

product

permutations

combinations

combinations_with_replacement

組合生成器

3.1 product

product 用於求多個可迭代物件的笛卡爾積,它跟巢狀的 for 迴圈等價。它的一般使用形式如下:

product(iter1, iter2, ... iterN, [repeat=1])

其中,repeat 是一個關鍵字引數,用於指定重複生成序列的次數,

>>> from itertools import product
>>>
>>> for item in product('ABCD', 'xy'):
...     print item
...
('A', 'x')
('A', 'y')
('B', 'x')
('B', 'y')
('C', 'x')
('C', 'y')
('D', 'x')
('D', 'y')
>>>
>>> list(product('ab', range(3)))
[('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2)]
>>>
>>> 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')]
>>>

組合生成器

3.2 permutations

permutations 用於生成一個排列,它的一般使用形式如下:

permutations(iterable[, r])

其中,r 指定生成排列的元素的長度,如果不指定,則預設為可迭代物件的元素長度。

>>> from itertools import permutations
>>>
>>> permutations('ABC', 2)
<itertools.permutations object at 0x1074d9c50>
>>>
>>> list(permutations('ABC', 2))
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
>>>
>>> list(permutations('ABC'))
[('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]
>>>

組合生成器

3.3 combinations

combinations 用於求序列的組合,它的使用形式如下:

combinations(iterable, r)

其中,r 指定生成組合的元素的長度。

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

組合生成器

3.4 combinations-with-replacement

combinations_with_replacementcombinations 類似,但它生成的組合包含自身元素。

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

4,總結

 

itertools 模組提供了很多用於產生多種型別迭代器的函式,它們的返回值不是 list,而是迭代器。這個標準庫的靈活使用可以大大提高我們的程式設計效率哦!