itertools模块包含一组函数用于处理序列数据集。
合并和分解迭代器
- chain 用于合并多个迭代器, 利用chain可以轻松处理多个序列。
from itertools import chain
for i in chain([1,2,3], ['a', 'b', 'c'])
print i
结果为:
1
2
3
a
b
c
- izip 用于将多个迭代器中的元素组合到一个元组中
from itertools import izip
for i in izip([1,2,3], ['a','b', 'c']):
print i
结果为:
(1,'a')
(2,'b')
(3,'c')
- islice 返回一个迭代器,它按索引返回由输入迭代器所选的元素。
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
count()用于生成无限连续整数,后面会讲到。
- tee 根据一个原输入迭代器返回多个独立的迭代器, 默认为两个。
from itertools import *
r = islice(count(), 5)
i1, i2 = tee(r)
tee()创建的迭代器共享其输入迭代器,所以一旦创建了新迭代器,就不应该再使用远迭代器。
如果原迭代器的值已经使用,新迭代器不会再生成这些值。
转换输入
- imap 返回一个迭代器,它对输入迭代器中的值调用一个函数并返回结果。imap函数的工作方式类似于内置函数map,只不过只要某个输入迭代器中的元素使用完,imap函数就会停止。
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
- starmap starmap类似于imap函数,不过它并不是使用多个迭代器来构建一个tuple, 而是使用*语法来分解一个迭代器中的元素来作为映射函数的参数。
from itertools import *
values = [[0,5], [1,6], [2,7], [3,8]]
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
imap的函数映射名为f(i1, i2), 而传入starmap()的映射函数名为f(*i)。
生成新值
- count 返回一个迭代器,能够无限的生成连续整数,第一个数可以作为参数传入,默认为0,这里没有上界参数。
from itertools import *
for i in izip(count(1), ['a', 'b', 'c']):
print i
输出结果如下:
(1, 'a')
(2, 'b')
(3, 'c')
- cycle 返回一个迭代器,它会无限的重复给定参数的内容。由于必须记住输入迭代器的全部内容,因此如果这个迭代器比较长,可能会比较消耗内存。
from itertools import *
for i in izip(xrange(7), cycle(['a', 'b', 'c'])):
print i
输出结果如下:
(0, 'a')
(1, 'b')
(2, 'c')
(3, 'a')
(4, 'b')
(5, 'c')
(6, 'a')
- repeat 返回一个迭代器,每次访问都会生成相同的值。
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
repeat返回的迭代器会一直返回数据,除非提供了可选的times参数来限制次数。
过滤
- dropwhile 该函数返回一个迭代器,它会生成输入迭代器中条件第一次为false之后的元素。
from itertools import *
def should_drop(x):
print "Testing:", x
return (x<1)
for i in dropwhile(should_drop, [-1, 0, 1, 2, -2]):
print "Yielding:", i
输出结果如下:
Testing: -1
Testing: 0
Testing: 1
Yielding: 1
Yielding: 2
Yielding: -2
dropwhile()函数并不会过滤输入的每一个元素,第一次条件为false之后,输入中所有余下的元素都会返回。
- takewhile 该函数与dropwhile正好相反,它也返回一个迭代器,这个迭代器生成输入迭代器中条件第一次为false之前的元素。
from itertools import *
def should_take(x):
print "Testing:", x
return (x<2)
for i in takewhile(should_take, [-1, 0, 1, 2, -2]):
print "Yielding:", i
输出结果如下:
Testing: -1
Yielding: -1
Testing: 0
Yielding: 0
Testing: 1
Yielding: 1
Testing: 2
- ifilter 该函数返回一个迭代器,它的工作方式与filter函数类似,只返回满足条件的元素。
from itertools import *
def check_item(x):
print "Testing:", x
return (x<1)
for i in ifilter(check_item, [-1, 0, 1, 2, -2]):
print "Yielding:", i
输出结果如下:
Testing: -1
Yielding: -1
Testing: 0
Yielding: 0
Testing: 1
Testing: 2
Testing: -2
Yielding: -2
- ifilterfalse 该函数与ifilter正好相反,只返回不满足条件的元素。
from itertools import *
def check_item(x):
print "Testing:", x
return (x<1)
for i in ifilterfalse(check_item, [-1, 0, 1, 2, -2]):
print "Yielding:", i
输出结果如下:
Testing: -1
Testing: 0
Testing: 1
Yielding: 1
Testing: 2
Yielding: 2
Testing: -2
数据分组
- groupby 该函数返回一个迭代器,它会生成一个公共键组织的值集。
from itertools import *
import operator
import pprint
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "(%s, %s)" % (self.x, self.y)
def __cmp__(self, other):
return cmp((self.x, self.y), (other.x, other.y))
data = list(imap(Point, cycle(islice(count(), 3)), islice(count(), 7)))
print "Data:"
pprint.pprint(data, width =69)
print
print "Grouped, unsorted"
for k, g in groupby(data, operator.attrgetter('x')):
print k, list(g)
print
data.sort()
print "Sorted:"
pprint.pprint(data, width=69)
print
print "Grouped, sorted"
for k, g in groupby(data, operator.attrgetter('x')):
print k, list(g)
print
输出结果如下:
Data:
[(0, 0), (1, 1), (2, 2), (0, 3), (1, 4), (2, 5), (0, 6)]
Grouped, unsorted
0 [(0, 0)]
1 [(1, 1)]
2 [(2, 2)]
0 [(0, 3)]
1 [(1, 4)]
2 [(2, 5)]
0 [(0, 6)]
Sorted:
[(0, 0), (0, 3), (0, 6), (1, 1), (1, 4), (2, 2), (2, 5)]
Grouped, sorted
0 [(0, 0), (0, 3), (0, 6)]
1 [(1, 1), (1, 4)]
2 [(2, 2), (2, 5)]
注意输入序列需要根据键值排序,以保证得到预期的分组。
网友评论