Python基礎(chǔ)文章集合請移步论悴。
itertools 模塊
該模塊包含了一系列處理可迭代對象(sequence-like)的函數(shù)移层,從此迭代更任性漠酿。
迭代器有一些特點(diǎn),比如lazy吉嚣,也就是只有用到的時候才讀入到內(nèi)存里梢薪,這樣更快更省內(nèi)存;比如只能調(diào)用一次尝哆,會被消耗掉秉撇。
import itertools as itls
合并迭代器: chain()與izip()
chain()
函數(shù)接收n個可迭代對象,然后返回一個他們的合集的迭代器秋泄,縱向合并琐馆,上例子。
for i in itls.chain([1,2,3],['a','b','c']):
print i,
1 2 3 a b c
izip()
函數(shù)接收n個可迭代對象恒序,然后將其合并成tuples瘦麸,橫向合并,功能類似zip()
歧胁,只是返回的是iterator滋饲,而不是list。
for i, j in itls.izip([1,2,3],['a','b','c']):
print i, j
1 a
2 b
3 c
切分迭代器: islice()
islice()
函數(shù)接收一個迭代器喊巍,然后返回其切片屠缭,類似于list
的slice
切片操作。參數(shù)有start
崭参,stop
和step
呵曹,其中start
和step
參數(shù)時可選參數(shù)。
print "Stop at 5:"
for i in itls.islice(itls.count(),5):
print i,
Stop at 5:
0 1 2 3 4
print "Start at 5, Stop at 10:"
for i in itls.islice(itls.count(),5,10):
print i,
Start at 5, Stop at 10:
5 6 7 8 9
print "By tens to 100:"
for i in itls.islice(itls.count(),0,100,10):
print i,
By tens to 100:
0 10 20 30 40 50 60 70 80 90
復(fù)制迭代器: tee()
與Unix里tee
方法語意一樣何暮,這里接收一個迭代器奄喂,然后返回n個(default 2)一樣的迭代器。
r = itls.islice(itls.count(),4)
i1, i2, i3 = itls.tee(r,3) # i1 and i2, like a copy
for i, j, k in itls.izip(i1,i2,i3):
print i, j, k
0 0 0
1 1 1
2 2 2
3 3 3
有一點(diǎn)值得注意海洼,初始的iterator不宜繼續(xù)使用砍聊,如果你使用(consume),那新的迭代器就不會產(chǎn)生這些值了贰军,見例子玻蝌。
r = itls.islice(itls.count(),4)
i1, i2 = itls.tee(r)
for i in r:
print 'r:', i
if i > 0:
break
for i in i1:
print 'i1:', i
for i in i2:
print 'i2:', i
r: 0
r: 1
i1: 2
i1: 3
i2: 2
i2: 3
可以看出,初始迭代器消耗了0,1词疼,在新產(chǎn)生的迭代器里俯树,就不會出現(xiàn)這些值了。
Map迭代器
imap()
函數(shù)對迭代器進(jìn)行轉(zhuǎn)換贰盗,類似于python內(nèi)置的map()
函數(shù)许饿。下例把xrange(5)
乘以2。
print "Doubles:"
for i in itls.imap(lambda x: 2*x, xrange(5)):
print i,
Doubles:
0 2 4 6 8
imap()
可以同時接受多個可迭代對象舵盈,進(jìn)行map
操作陋率。
print "Multiples:"
for i in itls.imap(lambda x,y:(x, y, x*y), xrange(5),xrange(5,10)):
print '%d * %d = %d' % i
Multiples:
0 * 5 = 0
1 * 6 = 6
2 * 7 = 14
3 * 8 = 24
4 * 9 = 36
starmap()
與imap()
功能類似球化,但有點(diǎn)區(qū)別,starmap()
可以從tuple
里解析出多個參數(shù)瓦糟,而imap()
只能從多個課迭代對象獲取多個參數(shù)筒愚,看例子。
values = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]
for i in itls.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
產(chǎn)生新迭代器
count()
菩浙,cycle()
和repeat()
函數(shù)提供了幾個產(chǎn)生迭代器的便捷操作巢掺,非常nice。
count()
產(chǎn)生連續(xù)的整數(shù)劲蜻,有下限(默認(rèn)0)陆淀,沒有上限(可以用xrange())。
for i in itls.izip(itls.count(1),['a','b','c']):
print i
(1, 'a')
(2, 'b')
(3, 'c')
cycle()
無限重復(fù)給定的可迭代對象先嬉。
i = 0
for item in itls.cycle(['a','b','c']):
i += 1
if i == 7:
break
print (i, item)
(1, 'a')
(2, 'b')
(3, 'c')
(4, 'a')
(5, 'b')
(6, 'c')
repeat()
重復(fù)給定的值轧苫,n次。
for i in itls.repeat('over-and-over',3):
print i
over-and-over
over-and-over
over-and-over
當(dāng)需要給一個序列添加一個不變對象的時候疫蔓,用repeat()
和imap()
或izip()
的combo特別有用含懊。
for i,s in itls.izip(itls.count(), itls.repeat('over-and-over',3)):
print i, s
0 over-and-over
1 over-and-over
2 over-and-over
for i in itls.imap(lambda x,y:(x,y,x*y),itls.repeat(2),xrange(5)):
print '%d * %d = %d' % i
2 * 0 = 0
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
過濾迭代器
類似于內(nèi)置的filter()
功能,實(shí)現(xiàn)迭代器的篩選鳄袍。
dropwhile()
對item進(jìn)行判斷绢要,如果判斷為True
吏恭,繼續(xù)拗小;如果判斷為False
,不繼續(xù)drop了樱哼,只drop
之前判斷為True
的哀九,保留之后的所有items,不再進(jìn)行判斷搅幅,全部保留阅束。
def should_drop(x):
print 'Testing:', x
return x < 1
for i in itls.dropwhile(should_drop,[ -1, 0, 1, 2, 3, 1, -2 ]):
print 'Yielding:', i
Testing: -1
Testing: 0
Testing: 1
Yielding: 1
Yielding: 2
Yielding: 3
Yielding: 1
Yielding: -2
takewhile()
與dropwhile()
功能相反,當(dāng)判斷為False
的時候茄唐,就不繼續(xù)take了息裸,只保留之前判斷為真item。
def should_take(x):
print 'Testing:', x
return x < 2
for i in itls.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
ifilter()
dropwhile()
和takewhile()
都不是對所有元素過濾沪编,而ifilter()
則盡職盡責(zé)地對所有元素過濾呼盆。與其對應(yīng)的是ifilterfalse()
,只保留判定為False
的item蚁廓。
def check_item(x):
print 'Testing:', x
return x < 1
for i in itls.ifilter(check_item, [ -1, 0, 1, 2, 3, -2 ]):
print 'Yielding:', i
Testing: -1
Yielding: -1
Testing: 0
Yielding: 0
Testing: 1
Testing: 2
Testing: 3
Testing: -2
Yielding: -2
Group迭代器
groupby(iterable[, keyfunc])
Create an iterator which returns(key, sub-iterator) grouped by each value of key(value)
按給定的key
對可迭代對象分組访圃,返回sub-iterator
。
things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "speed boat"), ("vehicle", "school bus")]
groupby()
接收兩個參數(shù)相嵌,一個the data to group
腿时,一個是the function to group it with
况脆。
for key, group in itls.groupby(things, lambda x: x[0]):
print key, group
animal <itertools._grouper object at 0x10bce2150>
plant <itertools._grouper object at 0x10bce2190>
vehicle <itertools._grouper object at 0x10bce2150>
可以看出,分組后批糟,返回三個sub-iterator
格了,我們可以再用一層循環(huán)訪問。
for key, group in itls.groupby(things, lambda x:x[0]):
for thing in group:
print "A %s is a %s." % (thing[1], key)
print ""
A bear is a animal.
A duck is a animal.
A cactus is a plant.
A speed boat is a vehicle.
A school bus is a vehicle.
且慢跃赚,值得注意的一點(diǎn)是笆搓,在group之前,務(wù)必要按key排序纬傲,因?yàn)?code>groupby方法遍歷對象满败,當(dāng)key變化的時候,就會新產(chǎn)生一個group叹括。有例為證算墨!
things = [("animal", "bear"), ("plant", "cactus"), ("animal", "duck")]
for key, group in itls.groupby(things, lambda x: x[0]):
print key, group
animal <itertools._grouper object at 0x10bce2410>
plant <itertools._grouper object at 0x10bce2490>
animal <itertools._grouper object at 0x10bce2410>
本來是應(yīng)該分兩組的,結(jié)果是三組汁雷,就是因?yàn)闆]有排序净嘀。
new_things = sorted(things,key=lambda x: x[0])
for key, group in itls.groupby(new_things, lambda x:x[0]):
print key, group
animal <itertools._grouper object at 0x10bce2350>
plant <itertools._grouper object at 0x10bce2410>
這個看上去就對了!