亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python itertools模塊詳解

系統(tǒng) 1529 0

這貨很強(qiáng)大, 必須掌握

文檔 鏈接 http://docs.python.org/2/library/itertools.html

pymotw 鏈接 http://pymotw.com/2/itertools/

基本是基于文檔的翻譯和補(bǔ)充,相當(dāng)于翻譯了

itertools用于高效循環(huán)的迭代函數(shù)集合

組成

總體,整體了解

無(wú)限迭代器

復(fù)制代碼 代碼如下:

迭代器???????? 參數(shù)???????? 結(jié)果??????????????????????????????????????????????? 例子
count()???? start, [step]?? start, start+step, start+2*step, ...??????????????? count(10) --> 10 11 12 13 14 ...
cycle()???? p?????????????? p0, p1, ... plast, p0, p1, ...????????????????????? cycle('ABCD') --> A B C D A B C D ...
repeat()??? elem [,n]?????? elem, elem, elem, ... endlessly or up to n times??? repeat(10, 3) --> 10 10 10

處理輸入序列迭代器
復(fù)制代碼 代碼如下:

迭代器????????? 參數(shù)??????????? 結(jié)果??????????????????????????????????????? 例子
chain()???? p, q, ...?????????? p0, p1, ... plast, q0, q1, ...????????????? chain('ABC', 'DEF') --> A B C D E F
compress()? data, selectors???? (d[0] if s[0]), (d[1] if s[1]), ...???????? compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
dropwhile() pred, seq?????????? seq[n], seq[n+1], starting when pred fails? dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
groupby()?? iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v)
ifilter()?? pred, seq?????????? elements of seq where pred(elem) is True??? ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
ifilterfalse()? pred, seq?????? elements of seq where pred(elem) is False?? ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
islice()??? seq, [start,] stop [, step] elements from seq[start:stop:step]? islice('ABCDEFG', 2, None) --> C D E F G
imap()????? func, p, q, ...???? func(p0, q0), func(p1, q1), ...???????????? imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
starmap()?? func, seq?????????? func(*seq[0]), func(*seq[1]), ...?????????? starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
tee()?????? it, n?????????????? it1, it2 , ... itn splits one iterator into n
takewhile() pred, seq?????????? seq[0], seq[1], until pred fails??????????? takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
izip()????? p, q, ...?????????? (p[0], q[0]), (p[1], q[1]), ...???????????? izip('ABCD', 'xy') --> Ax By
izip_longest()? p, q, ...?????? (p[0], q[0]), (p[1], q[1]), ...???????????? izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-

組合生成器

復(fù)制代碼 代碼如下:

迭代器????????? 參數(shù)??????????????????????? 結(jié)果
product()?????? p, q, ... [repeat=1]??????? cartesian product, equivalent to a nested for-loop
permutations()? p[, r]????????????????????? r-length tuples, all possible orderings, no repeated elements
combinations()? p, r??????????????????????? r-length tuples, in sorted order, no repeated elements
combinations_with_replacement() p, r??????? r-length tuples, in sorted order, with repeated elements
product('ABCD', repeat=2)?????????????????? AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)???????????????????? AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)???????????????????? AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2)??? AA AB AC AD BB BC BD CC CD DD

第一部分

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

創(chuàng)建一個(gè)迭代器,生成從n開(kāi)始的連續(xù)整數(shù),如果忽略n,則從0開(kāi)始計(jì)算(注意:此迭代器不支持長(zhǎng)整數(shù))

如果超出了sys.maxint,計(jì)數(shù)器將溢出并繼續(xù)從-sys.maxint-1開(kāi)始計(jì)算。

定義

復(fù)制代碼 代碼如下:

def count(start=0, step=1):
??? # count(10) --> 10 11 12 13 14 ...
??? # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
??? n = start
??? while True:
??????? yield n
??????? n += step

等同于(start + step * i for i in count())

使用

復(fù)制代碼 代碼如下:

from itertools import *

for i in izip(count(1), ['a', 'b', 'c']):
??? print i

(1, 'a')
(2, 'b')
(3, 'c')

itertools.repeat(object[, times])

創(chuàng)建一個(gè)迭代器,重復(fù)生成object,times(如果已提供)指定重復(fù)計(jì)數(shù),如果未提供times,將無(wú)止盡返回該對(duì)象。

定義

復(fù)制代碼 代碼如下:

def repeat(object, times=None):
??? # repeat(10, 3) --> 10 10 10
??? if times is None:
??????? while True:
??????????? yield object
??? else:
??????? for i in xrange(times):
??????????? yield object

使用
復(fù)制代碼 代碼如下:

from itertools import *

for i in repeat('over-and-over', 5):
??? print i

over-and-over
over-and-over
over-and-over
over-and-over
over-and-over

第二部分
itertools.chain(*iterables)

將多個(gè)迭代器作為參數(shù), 但只返回單個(gè)迭代器, 它產(chǎn)生所有參數(shù)迭代器的內(nèi)容, 就好像他們是來(lái)自于一個(gè)單一的序列.

復(fù)制代碼 代碼如下:

def chain(*iterables):
??? # chain('ABC', 'DEF') --> A B C D E F
??? for it in iterables:
??????? for element in it:
??????????? yield element

使用
復(fù)制代碼 代碼如下:

from itertools import *

for i in chain([1, 2, 3], ['a', 'b', 'c']):
??? print i
1
2
3
a
b
c


from itertools import chain, imap
def flatmap(f, items):
??? return chain.from_iterable(imap(f, items))
>>> list(flatmap(os.listdir, dirs))
>>> ['settings.py', 'wsgi.py', 'templates', 'app.py',
???? 'templates', 'index.html, 'config.json']

itertools.compress(data, selectors)

提供一個(gè)選擇列表,對(duì)原始數(shù)據(jù)進(jìn)行篩選

復(fù)制代碼 代碼如下:

def compress(data, selectors):
??? # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
??? return (d for d, s in izip(data, selectors) if s)
itertools.dropwhile(predicate, iterable)

創(chuàng)建一個(gè)迭代器,只要函數(shù)predicate(item)為T(mén)rue,就丟棄iterable中的項(xiàng),如果predicate返回False,就會(huì)生成iterable中的項(xiàng)和所有后續(xù)項(xiàng)。

即:在條件為false之后的第一次, 返回迭代器中剩下來(lái)的項(xiàng).

復(fù)制代碼 代碼如下:

def dropwhile(predicate, iterable):
??? # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
??? iterable = iter(iterable)
??? for x in iterable:
??????? if not predicate(x):
??????????? yield x
??????????? break
??? for x in iterable:
??????? yield x

使用

復(fù)制代碼 代碼如下:

from itertools import *

def should_drop(x):
??? print 'Testing:', x
??? return (x<1)

for i in dropwhile(should_drop, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
??? print 'Yielding:', i

Testing: -1
Testing: 0
Testing: 1
Yielding: 1
Yielding: 2
Yielding: 3
Yielding: 4
Yielding: 1
Yielding: -2

itertools.groupby(iterable[, key])

返回一個(gè)產(chǎn)生按照key進(jìn)行分組后的值集合的迭代器.

如果iterable在多次連續(xù)迭代中生成了同一項(xiàng),則會(huì)定義一個(gè)組,如果將此函數(shù)應(yīng)用一個(gè)分類(lèi)列表,那么分組將定義該列表中的所有唯一項(xiàng),key(如果已提供)是一個(gè)函數(shù),應(yīng)用于每一項(xiàng),如果此函數(shù)存在返回值,該值將用于后續(xù)項(xiàng)而不是該項(xiàng)本身進(jìn)行比較,此函數(shù)返回的迭代器生成元素(key, group),其中key是分組的鍵值,group是迭代器,生成組成該組的所有項(xiàng)。

即:按照keyfunc函數(shù)對(duì)序列每個(gè)元素執(zhí)行后的結(jié)果分組(每個(gè)分組是一個(gè)迭代器), 返回這些分組的迭代器

等價(jià)于

復(fù)制代碼 代碼如下:

class groupby(object):
??? # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
??? # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
??? def __init__(self, iterable, key=None):
??????? if key is None:
??????????? key = lambda x: x
??????? self.keyfunc = key
??????? self.it = iter(iterable)
??????? self.tgtkey = self.currkey = self.currvalue = object()
??? def __iter__(self):
??????? return self
??? def next(self):
??????? while self.currkey == self.tgtkey:
??????????? self.currvalue = next(self.it)??? # Exit on StopIteration
??????????? self.currkey = self.keyfunc(self.currvalue)
??????? self.tgtkey = self.currkey
??????? return (self.currkey, self._grouper(self.tgtkey))
??? def _grouper(self, tgtkey):
??????? while self.currkey == tgtkey:
??????????? yield self.currvalue
??????????? self.currvalue = next(self.it)??? # Exit on StopIteration
??????????? self.currkey = self.keyfunc(self.currvalue)

應(yīng)用

復(fù)制代碼 代碼如下:

from itertools import groupby
qs = [{'date' : 1},{'date' : 2}]
[(name, list(group)) for name, group in itertools.groupby(qs, lambda p:p['date'])]

Out[77]: [(1, [{'date': 1}]), (2, [{'date': 2}])]


>>> from itertools import *
>>> 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']

另一個(gè)例子

復(fù)制代碼 代碼如下:

from itertools import *
from operator import itemgetter

d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
di = sorted(d.iteritems(), key=itemgetter(1))
for k, g in groupby(di, key=itemgetter(1)):
??? print k, map(itemgetter(0), g)


1 ['a', 'c', 'e']
2 ['b', 'd', 'f']
3 ['g']

itertools.ifilter(predicate, iterable)

返回的是迭代器類(lèi)似于針對(duì)列表的內(nèi)置函數(shù) filter() , 它只包括當(dāng)測(cè)試函數(shù)返回true時(shí)的項(xiàng). 它不同于 dropwhile()

創(chuàng)建一個(gè)迭代器,僅生成iterable中predicate(item)為T(mén)rue的項(xiàng),如果predicate為None,將返回iterable中所有計(jì)算為T(mén)rue的項(xiàng)

對(duì)函數(shù)func執(zhí)行返回真的元素的迭代器

復(fù)制代碼 代碼如下:

def ifilter(predicate, iterable):
??? # ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
??? if predicate is None:
??????? predicate = bool
??? for x in iterable:
??????? if predicate(x):
??????????? yield x

使用

復(fù)制代碼 代碼如下:

from itertools import *

def check_item(x):
??? print 'Testing:', x
??? return (x<1)

for i in ifilter(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
??? print 'Yielding:', i

Testing: -1
Yielding: -1
Testing: 0
Yielding: 0
Testing: 1
Testing: 2
Testing: 3
Testing: 4
Testing: 1
Testing: -2
Yielding: -2

itertools.ifilterfalse(predicate, iterable)

和ifilter(函數(shù)相反 , 返回一個(gè)包含那些測(cè)試函數(shù)返回false的項(xiàng)的迭代器)

創(chuàng)建一個(gè)迭代器,僅生成iterable中predicate(item)為False的項(xiàng),如果predicate為None,則返回iterable中所有計(jì)算為False的項(xiàng) 對(duì)函數(shù)func執(zhí)行返回假的元素的迭代器

復(fù)制代碼 代碼如下:

def ifilterfalse(predicate, iterable):
??? # ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
??? if predicate is None:
??????? predicate = bool
??? for x in iterable:
??????? if not predicate(x):
??????????? yield x

使用

復(fù)制代碼 代碼如下:

from itertools import *

def check_item(x):
??? print 'Testing:', x
??? return (x<1)

for i in ifilterfalse(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
??? print 'Yielding:', i

Testing: -1
Testing: 0
Testing: 1
Yielding: 1
Testing: 2
Yielding: 2
Testing: 3
Yielding: 3
Testing: 4
Yielding: 4
Testing: 1
Yielding: 1
Testing: -2

itertools.islice(iterable, stop)

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

返回的迭代器是返回了輸入迭代器根據(jù)索引來(lái)選取的項(xiàng)

創(chuàng)建一個(gè)迭代器,生成項(xiàng)的方式類(lèi)似于切片返回值: iterable[start : stop : step],將跳過(guò)前start個(gè)項(xiàng),迭代在stop所指定的位置停止,step指定用于跳過(guò)項(xiàng)的步幅。 與切片不同,負(fù)值不會(huì)用于任何start,stop和step, 如果省略了start,迭代將從0開(kāi)始,如果省略了step,步幅將采用1.

返回序列seq的從start開(kāi)始到stop結(jié)束的步長(zhǎng)為step的元素的迭代器

復(fù)制代碼 代碼如下:

def islice(iterable, *args):
??? # islice('ABCDEFG', 2) --> A B
??? # islice('ABCDEFG', 2, 4) --> C D
??? # islice('ABCDEFG', 2, None) --> C D E F G
??? # islice('ABCDEFG', 0, None, 2) --> A C E G
??? s = slice(*args)
??? it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
??? nexti = next(it)
??? for i, element in enumerate(iterable):
??????? if i == nexti:
??????????? yield element
??????????? nexti = next(it)

使用

復(fù)制代碼 代碼如下:

from itertools import *

print 'Stop at 5:'
for i in islice(count(), 5):
??? print i

print 'Start at 5, Stop at 10:'
for i in islice(count(), 5, 10):
??? print i

print 'By tens to 100:'
for i in islice(count(), 0, 100, 10):
??? print i

Stop at 5:
0
1
2
3
4
Start at 5, Stop at 10:
5
6
7
8
9
By tens to 100:
0
10
20
30
40
50
60
70
80
90

itertools.imap(function, *iterables)

創(chuàng)建一個(gè)迭代器,生成項(xiàng)function(i1, i2, ..., iN),其中i1,i2...iN分別來(lái)自迭代器iter1,iter2 ... iterN,如果function為None,則返回(i1, i2, ..., iN)形式的元組,只要提供的一個(gè)迭代器不再生成值,迭代就會(huì)停止。

即:返回一個(gè)迭代器, 它是調(diào)用了一個(gè)其值在輸入迭代器上的函數(shù), 返回結(jié)果. 它類(lèi)似于內(nèi)置函數(shù) map() , 只是前者在任意輸入迭代器結(jié)束后就停止(而不是插入None值來(lái)補(bǔ)全所有的輸入).

返回序列每個(gè)元素被func執(zhí)行后返回值的序列的迭代器

復(fù)制代碼 代碼如下:

def imap(function, *iterables):
??? # imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
??? iterables = map(iter, iterables)
??? while True:
??????? args = [next(it) for it in iterables]
??????? if function is None:
??????????? yield tuple(args)
??????? else:
??????????? yield function(*args)

使用

復(fù)制代碼 代碼如下:

from itertools import *

print 'Doubles:'
for i in imap(lambda x:2*x, xrange(5)):
??? print i

print 'Multiples:'
for i in imap(lambda x,y:(x, y, x*y), xrange(5), xrange(5,10)):
??? print '%d * %d = %d' % i

Doubles:
0
2
4
6
8
Multiples:
0 * 5 = 0
1 * 6 = 6
2 * 7 = 14
3 * 8 = 24
4 * 9 = 36

itertools.starmap(function, iterable)

創(chuàng)建一個(gè)迭代器,生成值func(*item),其中item來(lái)自iterable,只有當(dāng)iterable生成的項(xiàng)適用于這種調(diào)用函數(shù)的方式時(shí),此函數(shù)才有效。

對(duì)序列seq的每個(gè)元素作為func的參數(shù)列表執(zhí)行, 返回執(zhí)行結(jié)果的迭代器

復(fù)制代碼 代碼如下:

def starmap(function, iterable):
??? # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
??? for args in iterable:
??????? yield function(*args)

使用
復(fù)制代碼 代碼如下:

from itertools import *

values = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]
for i in starmap(lambda x,y:(x, y, x*y), values):
??? print '%d * %d = %d' % i

0 * 5 = 0
1 * 6 = 6
2 * 7 = 14
3 * 8 = 24
4 * 9 = 36

itertools.tee(iterable[, n=2])

返回一些基于單個(gè)原始輸入的獨(dú)立迭代器(默認(rèn)為2). 它和Unix上的tee工具有點(diǎn)語(yǔ)義相似, 也就是說(shuō)它們都重復(fù)讀取輸入設(shè)備中的值并將值寫(xiě)入到一個(gè)命名文件和標(biāo)準(zhǔn)輸出中

從iterable創(chuàng)建n個(gè)獨(dú)立的迭代器,創(chuàng)建的迭代器以n元組的形式返回,n的默認(rèn)值為2,此函數(shù)適用于任何可迭代的對(duì)象,但是,為了克隆原始迭代器,生成的項(xiàng)會(huì)被緩存,并在所有新創(chuàng)建的迭代器中使用,一定要注意,不要在調(diào)用tee()之后使用原始迭代器iterable,否則緩存機(jī)制可能無(wú)法正確工作。

把一個(gè)迭代器分為n個(gè)迭代器, 返回一個(gè)元組.默認(rèn)是兩個(gè)

復(fù)制代碼 代碼如下:

def tee(iterable, n=2):
??? it = iter(iterable)
??? deques = [collections.deque() for i in range(n)]
??? def gen(mydeque):
??????? while True:
??????????? if not mydeque:???????????? # when the local deque is empty
??????????????? newval = next(it)?????? # fetch a new value and
??????????????? for d in deques:??????? # load it to all the deques
??????????????????? d.append(newval)
??????????? yield mydeque.popleft()
??? return tuple(gen(d) for d in deques)

使用

復(fù)制代碼 代碼如下:

from itertools import *

r = islice(count(), 5)
i1, i2 = tee(r)

for i in i1:
??? print 'i1:', i
for i in i2:
??? print 'i2:', i

i1: 0
i1: 1
i1: 2
i1: 3
i1: 4
i2: 0
i2: 1
i2: 2
i2: 3
i2: 4

itertools.takewhile(predicate, iterable)

和dropwhile相反

創(chuàng)建一個(gè)迭代器,生成iterable中predicate(item)為T(mén)rue的項(xiàng),只要predicate計(jì)算為False,迭代就會(huì)立即停止。

即:從序列的頭開(kāi)始, 直到執(zhí)行函數(shù)func失敗.

復(fù)制代碼 代碼如下:

def takewhile(predicate, iterable):
??? # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
??? for x in iterable:
??????? if predicate(x):
??????????? yield x
??????? else:
??????????? break

使用

復(fù)制代碼 代碼如下:

from itertools import *

def should_take(x):
??? print 'Testing:', x
??? return (x<2)

for i in takewhile(should_take, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
??? print 'Yielding:', i

Testing: -1
Yielding: -1
Testing: 0
Yielding: 0
Testing: 1
Yielding: 1
Testing: 2

itertools.izip(*iterables)

返回一個(gè)合并了多個(gè)迭代器為一個(gè)元組的迭代器. 它類(lèi)似于內(nèi)置函數(shù)zip(), 只是它返回的是一個(gè)迭代器而不是一個(gè)列表

創(chuàng)建一個(gè)迭代器,生成元組(i1, i2, ... iN),其中i1,i2 ... iN 分別來(lái)自迭代器iter1,iter2 ... iterN,只要提供的某個(gè)迭代器不再生成值,迭代就會(huì)停止,此函數(shù)生成的值與內(nèi)置的zip()函數(shù)相同。

復(fù)制代碼 代碼如下:

izip(iter1, iter2, ... iterN):
返回:(it1[0],it2 [0], it3[0], ..), (it1[1], it2[1], it3[1], ..)...

def izip(*iterables):
??? # izip('ABCD', 'xy') --> Ax By
??? iterators = map(iter, iterables)
??? while iterators:
??????? yield tuple(map(next, iterators))

使用

復(fù)制代碼 代碼如下:

from itertools import *

for i in izip([1, 2, 3], ['a', 'b', 'c']):
??? print i
(1, 'a')
(2, 'b')
(3, 'c')


itertools.izip_longest(*iterables[, fillvalue])

與izip()相同,但是迭代過(guò)程會(huì)持續(xù)到所有輸入迭代變量iter1,iter2等都耗盡為止,如果沒(méi)有使用fillvalue關(guān)鍵字參數(shù)指定不同的值,則使用None來(lái)填充已經(jīng)使用的迭代變量的值。

復(fù)制代碼 代碼如下:

class ZipExhausted(Exception):
??? pass

def izip_longest(*args, **kwds):
??? # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
??? fillvalue = kwds.get('fillvalue')
??? counter = [len(args) - 1]
??? def sentinel():
??????? if not counter[0]:
??????????? raise ZipExhausted
??????? counter[0] -= 1
??????? yield fillvalue
??? fillers = repeat(fillvalue)
??? iterators = [chain(it, sentinel(), fillers) for it in args]
??? try:
??????? while iterators:
??????????? yield tuple(map(next, iterators))
??? except ZipExhausted:
??????? pass

第三部分

itertools.product(*iterables[, repeat])

笛卡爾積

創(chuàng)建一個(gè)迭代器,生成表示item1,item2等中的項(xiàng)目的笛卡爾積的元組,repeat是一個(gè)關(guān)鍵字參數(shù),指定重復(fù)生成序列的次數(shù)。

復(fù)制代碼 代碼如下:

def product(*args, **kwds):
??? # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
??? # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
??? pools = map(tuple, args) * kwds.get('repeat', 1)
??? result = [[]]
??? for pool in pools:
??????? result = [x+[y] for x in result for y in pool]
??? for prod in result:
??????? yield tuple(prod)

例子

復(fù)制代碼 代碼如下:

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')

itertools.permutations(iterable[, r])

排列

創(chuàng)建一個(gè)迭代器,返回iterable中所有長(zhǎng)度為r的項(xiàng)目序列,如果省略了r,那么序列的長(zhǎng)度與iterable中的項(xiàng)目數(shù)量相同: 返回p中任意取r個(gè)元素做排列的元組的迭代器

復(fù)制代碼 代碼如下:

def permutations(iterable, r=None):
??? # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
??? # permutations(range(3)) --> 012 021 102 120 201 210
??? pool = tuple(iterable)
??? n = len(pool)
??? r = n if r is None else r
??? if r > n:
??????? return
??? indices = range(n)
??? cycles = range(n, n-r, -1)
??? yield tuple(pool[i] for i in indices[:r])
??? while n:
??????? for i in reversed(range(r)):
??????????? cycles[i] -= 1
??????????? if cycles[i] == 0:
??????????????? indices[i:] = indices[i+1:] + indices[i:i+1]
??????????????? cycles[i] = n - i
??????????? else:
??????????????? j = cycles[i]
??????????????? indices[i], indices[-j] = indices[-j], indices[i]
??????????????? yield tuple(pool[i] for i in indices[:r])
??????????????? break
??????? else:
??????????? return
也可以用product實(shí)現(xiàn)

def permutations(iterable, r=None):
??? pool = tuple(iterable)
??? n = len(pool)
??? r = n if r is None else r
??? for indices in product(range(n), repeat=r):
??????? if len(set(indices)) == r:
??????????? yield tuple(pool[i] for i in indices)

itertools.combinations(iterable, r)

創(chuàng)建一個(gè)迭代器,返回iterable中所有長(zhǎng)度為r的子序列,返回的子序列中的項(xiàng)按輸入iterable中的順序排序 (不帶重復(fù))

復(fù)制代碼 代碼如下:

def combinations(iterable, r):
??? # combinations('ABCD', 2) --> AB AC AD BC BD CD
??? # combinations(range(4), 3) --> 012 013 023 123
??? pool = tuple(iterable)
??? n = len(pool)
??? if r > n:
??????? return
??? indices = range(r)
??? yield tuple(pool[i] for i in indices)
??? while True:
??????? for i in reversed(range(r)):
??????????? if indices[i] != i + n - r:
??????????????? break
??????? else:
??????????? return
??????? indices[i] += 1
??????? for j in range(i+1, r):
??????????? indices[j] = indices[j-1] + 1
??????? yield tuple(pool[i] for i in indices)

#或者
def combinations(iterable, r):
??? pool = tuple(iterable)
??? n = len(pool)
??? for indices in permutations(range(n), r):
??????? if sorted(indices) == list(indices):
??????????? yield tuple(pool[i] for i in indices)

itertools.combinations_with_replacement(iterable, r)

創(chuàng)建一個(gè)迭代器,返回iterable中所有長(zhǎng)度為r的子序列,返回的子序列中的項(xiàng)按輸入iterable中的順序排序 (帶重復(fù))

復(fù)制代碼 代碼如下:

def combinations_with_replacement(iterable, r):
??? # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
??? pool = tuple(iterable)
??? n = len(pool)
??? if not n and r:
??????? return
??? indices = [0] * r
??? yield tuple(pool[i] for i in indices)
??? while True:
??????? for i in reversed(range(r)):
??????????? if indices[i] != n - 1:
??????????????? break
??????? else:
??????????? return
??????? indices[i:] = [indices[i] + 1] * (r - i)
??????? yield tuple(pool[i] for i in indices)
或者
def combinations_with_replacement(iterable, r):
??? pool = tuple(iterable)
??? n = len(pool)
??? for indices in product(range(n), repeat=r):
??????? if sorted(indices) == list(indices):
??????????? yield tuple(pool[i] for i in indices)

第四部分

擴(kuò)展

使用現(xiàn)有擴(kuò)展功能

復(fù)制代碼 代碼如下:

def take(n, iterable):
??? "Return first n items of the iterable as a list"
??? return list(islice(iterable, n))

def tabulate(function, start=0):
??? "Return function(0), function(1), ..."
??? return imap(function, count(start))

def consume(iterator, n):
??? "Advance the iterator n-steps ahead. If n is none, consume entirely."
??? # Use functions that consume iterators at C speed.
??? if n is None:
??????? # feed the entire iterator into a zero-length deque
??????? collections.deque(iterator, maxlen=0)
??? else:
??????? # advance to the empty slice starting at position n
??????? next(islice(iterator, n, n), None)

def nth(iterable, n, default=None):
??? "Returns the nth item or a default value"
??? return next(islice(iterable, n, None), default)

def quantify(iterable, pred=bool):
??? "Count how many times the predicate is true"
??? return sum(imap(pred, iterable))

def padnone(iterable):
??? """Returns the sequence elements and then returns None indefinitely.

??? Useful for emulating the behavior of the built-in map() function.
??? """
??? return chain(iterable, repeat(None))

def ncycles(iterable, n):
??? "Returns the sequence elements n times"
??? return chain.from_iterable(repeat(tuple(iterable), n))

def dotproduct(vec1, vec2):
??? return sum(imap(operator.mul, vec1, vec2))

def flatten(listOfLists):
??? "Flatten one level of nesting"
??? return chain.from_iterable(listOfLists)

def repeatfunc(func, times=None, *args):
??? """Repeat calls to func with specified arguments.

??? Example:? repeatfunc(random.random)
??? """
??? if times is None:
??????? return starmap(func, repeat(args))
??? return starmap(func, repeat(args, times))

def pairwise(iterable):
??? "s -> (s0,s1), (s1,s2), (s2, s3), ..."
??? a, b = tee(iterable)
??? next(b, None)
??? return izip(a, b)

def grouper(iterable, n, fillvalue=None):
??? "Collect data into fixed-length chunks or blocks"
??? # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
??? args = [iter(iterable)] * n
??? return izip_longest(fillvalue=fillvalue, *args)

def roundrobin(*iterables):
??? "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
??? # Recipe credited to George Sakkis
??? pending = len(iterables)
??? nexts = cycle(iter(it).next for it in iterables)
??? while pending:
??????? try:
??????????? for next in nexts:
??????????????? yield next()
??????? except StopIteration:
??????????? pending -= 1
??????????? nexts = cycle(islice(nexts, pending))

def powerset(iterable):
??? "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
??? s = list(iterable)
??? return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

def unique_everseen(iterable, key=None):
??? "List unique elements, preserving order. Remember all elements ever seen."
??? # unique_everseen('AAAABBBCCDAABBB') --> A B C D
??? # unique_everseen('ABBCcAD', str.lower) --> A B C D
??? seen = set()
??? seen_add = seen.add
??? if key is None:
??????? for element in ifilterfalse(seen.__contains__, iterable):
??????????? seen_add(element)
??????????? yield element
??? else:
??????? for element in iterable:
??????????? k = key(element)
??????????? if k not in seen:
??????????????? seen_add(k)
??????????????? yield element

def unique_justseen(iterable, key=None):
??? "List unique elements, preserving order. Remember only the element just seen."
??? # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
??? # unique_justseen('ABBCcAD', str.lower) --> A B C A D
??? return imap(next, imap(itemgetter(1), groupby(iterable, key)))

def iter_except(func, exception, first=None):
??? """ Call a function repeatedly until an exception is raised.

??? Converts a call-until-exception interface to an iterator interface.
??? Like __builtin__.iter(func, sentinel) but uses an exception instead
??? of a sentinel to end the loop.

??? Examples:
??????? bsddbiter = iter_except(db.next, bsddb.error, db.first)
??????? heapiter = iter_except(functools.partial(heappop, h), IndexError)
??????? dictiter = iter_except(d.popitem, KeyError)
??????? dequeiter = iter_except(d.popleft, IndexError)
??????? queueiter = iter_except(q.get_nowait, Queue.Empty)
??????? setiter = iter_except(s.pop, KeyError)

??? """
??? try:
??????? if first is not None:
??????????? yield first()
??????? while 1:
??????????? yield func()
??? except exception:
??????? pass

def random_product(*args, **kwds):
??? "Random selection from itertools.product(*args, **kwds)"
??? pools = map(tuple, args) * kwds.get('repeat', 1)
??? return tuple(random.choice(pool) for pool in pools)

def random_permutation(iterable, r=None):
??? "Random selection from itertools.permutations(iterable, r)"
??? pool = tuple(iterable)
??? r = len(pool) if r is None else r
??? return tuple(random.sample(pool, r))

def random_combination(iterable, r):
??? "Random selection from itertools.combinations(iterable, r)"
??? pool = tuple(iterable)
??? n = len(pool)
??? indices = sorted(random.sample(xrange(n), r))
??? return tuple(pool[i] for i in indices)

def random_combination_with_replacement(iterable, r):
??? "Random selection from itertools.combinations_with_replacement(iterable, r)"
??? pool = tuple(iterable)
??? n = len(pool)
??? indices = sorted(random.randrange(n) for i in xrange(r))
??? return tuple(pool[i] for i in indices)

def tee_lookahead(t, i):
??? """Inspect the i-th upcomping value from a tee object
??? while leaving the tee object at its current position.

??? Raise an IndexError if the underlying iterator doesn't
??? have enough values.

??? """
??? for value in islice(t.__copy__(), i, None):
??????? return value
??? raise IndexError(i)

自定義擴(kuò)展

將序列按大小切分,更好的性能

復(fù)制代碼 代碼如下:

from itertools import chain, islice
def chunks(iterable, size, format=iter):
??? it = iter(iterable)
??? while True:
??????? yield format(chain((it.next(),), islice(it, size - 1)))

>>> l = ["a", "b", "c", "d", "e", "f", "g"]
>>> for chunk in chunks(l, 3, tuple):...
??????? print chunk...
("a", "b", "c")
("d", "e", "f")
("g",)

補(bǔ)充

迭代工具,你最好的朋友

迭代工具模塊包含了操做指定的函數(shù)用于操作迭代器。想復(fù)制一個(gè)迭代器出來(lái)?鏈接兩個(gè)迭代器?以one liner(這里的one-liner只需一行代碼能搞定的任務(wù))用內(nèi)嵌的列表組合一組值?不使用list創(chuàng)建Map/Zip????,你要做的就是 import itertools,舉個(gè)例子吧:

四匹馬賽跑到達(dá)終點(diǎn)排名的所有可能性:

復(fù)制代碼 代碼如下:

>>> horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)

>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
?(1, 2, 4, 3),
?(1, 3, 2, 4),
?(1, 3, 4, 2),
?(1, 4, 2, 3),
?(1, 4, 3, 2),
?(2, 1, 3, 4),
?(2, 1, 4, 3),
?(2, 3, 1, 4),
?(2, 3, 4, 1),
?(2, 4, 1, 3),
?(2, 4, 3, 1),
?(3, 1, 2, 4),
?(3, 1, 4, 2),
?(3, 2, 1, 4),
?(3, 2, 4, 1),
?(3, 4, 1, 2),
?(3, 4, 2, 1),
?(4, 1, 2, 3),
?(4, 1, 3, 2),
?(4, 2, 1, 3),
?(4, 2, 3, 1),
?(4, 3, 1, 2),
?(4, 3, 2, 1)]

理解迭代的內(nèi)部機(jī)制: 迭代(iteration)就是對(duì)可迭代對(duì)象(iterables,實(shí)現(xiàn)了__iter__()方法)和迭代器(iterators,實(shí)現(xiàn)了__next__()方法)的一個(gè)操作過(guò)程。可迭代對(duì)象是任何可返回一個(gè)迭代器的對(duì)象,迭代器是應(yīng)用在迭代對(duì)象中迭代的對(duì)象,換一種方式說(shuō)的話(huà)就是:iterable對(duì)象的__iter__()方法可以返回iterator對(duì)象,iterator通過(guò)調(diào)用next()方法獲取其中的每一個(gè)值(譯者注),讀者可以結(jié)合Java API中的 Iterable接口和Iterator接口進(jìn)行類(lèi)比。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产乱在线观看视频 | 国产精品久久一区 | 伊人爱爱网 | 久久久久久网址 | 国产日产亚洲精品 | 麻豆精品国产免费观看 | 欧美高清免费精品国产自 | 天天干天天射综合网 | 久久综合色婷婷 | 青草在线视频 | 亚洲国产一区二区a毛片 | 欧美777精品久久久久网 | 久久亚洲国产中v天仙www | 欧美在线观看视频 | 久久99国产乱子伦精品免 | 91青青视频| 国产综合亚洲精品一区 | 久久久久女人精品毛片九一 | 亚洲黄色自拍 | 亚洲第3页 | 国产精品精品 | 91精品久久一区二区三区 | 久久久精品视频免费观看 | 久久国产视频精品 | 久久久免费精品视频 | 国产在线视频福利 | 草草视频免费观看 | 欧美一区二区久久精品 | 久久福利一区二区三区 | 国产精品久久久久久久久久妇女 | 色妞色综合久久夜夜 | 狠狠操天天操夜夜操 | 97av麻豆蜜桃一区二区 | 一级毛片无毒不卡直接观看 | 国产成人亚洲精品2020 | 国产一区二区在线免费观看 | 婷婷激情网站 | 99精品国产在现线免费 | 在线观看片成人免费视频 | 99热伊人| 国产综合精品在线 |