41 Python itertools

来源:互联网 发布:淘宝店铺o2o 编辑:程序博客网 时间:2024/04/29 00:42
from itertools import *import itertools

无限迭代器

# 和xrange很像,但是count没有上限natuals = itertools.count(start = 0, step = 2)print [next(natuals) for _ in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 无限重复一个序列的迭代器, 将传入的序列不断重复cycle = itertools.cycle("1234")print [next(cycle) for _ in range(10)]
['1', '2', '3', '4', '1', '2', '3', '4', '1', '2']

# 不断重复一个元素的迭代器, times代表重复的次数, 如果不赋值, 将会无限迭代repeat = itertools.repeat(0, times = 10)print [next(repeat) for _ in range(10)]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

处理输入序列

# tale(a, indices)类似于[a[key] for key in indices]take([0,1,2,3], [0,2,3])
array([0, 2, 3])
def func(x):    return x < 10# takewhile, 一旦遇到不满足条件的元素, 立即退出, 返回之前符合条件的元素l = itertools.takewhile(func, itertools.count(1))print type(l), tuple(l)# 100 > 10, 退出循环, 即使后面有符合条件的也不要l = itertools.takewhile(func, [1,3,100,2])print list(l)# takewhile的等价形式l = []for i in [1,3,100,2]:    if i < 10:        l.append(i)    else:        breakprint l
<type 'itertools.takewhile'> (1, 2, 3, 4, 5, 6, 7, 8, 9)[1, 3][1, 3]
def func(x):    return x < 10# 与takewhile相反, 一旦遇到不满足条件的元素, 则停止迭代, 返回之后的元素# 100 > 10, 返回100及其后续元素l = itertools.dropwhile(func, [1,3,100,2])print list(l)
[100, 2]

# 把迭代器中相邻的相同元素挑出来放在一起# 挑选规则是通过函数完成,两个元素的函数返回值相同,两个元素就视为相同, 函数返回值作为keyfor key, group in itertools.groupby('AAABbBAaA', lambda x:x.lower()):    print key, list(group)for key, group in itertools.groupby([0,0,2,2,3,3], lambda x:x%2):    print key, list(group)for key, group in itertools.groupby(["a", "b", "ab","cd", "c"], len):    print key, list(group)
a ['A', 'A', 'A']b ['B', 'b', 'B']a ['A', 'a', 'A']0 [0, 0, 2, 2]1 [3, 3]1 ['a', 'b']2 ['ab', 'cd']1 ['c']
# chain, 将迭代对象串联起来,生成一个更大的迭代器, 效率较高iters = chain("abc", list("def"), ("g", "h"), {"i":"j"})print [i for i in iters]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

# imap和map的区别:imap可以作用于无穷序列, imap返回的是一个可迭代对象# 如果两个序列的长度不一样, 以短的为准for x in itertools.imap(lambda x, y: x * y, [10, 20, 30], count(1)):    print x,# 同理ifilter,izip, ifilterfalse和ifilter函数相反, 返回函数返回false的迭代器
10 40 90

# 提供一个选择列表, 对原始数据筛选, 只选择列表中值为true的data = 'ABCDEF'selectors = [1,0,1,0,1,1]print list(compress(data, selectors))# 等价于compressprint list((d for d, s in izip(data, selectors) if s))
['A', 'C', 'E', 'F']['A', 'C', 'E', 'F']
values = [(1,2,3), (4,5,6), (7,8,9)]# map只能给函数传一个参数, starmap给函数传func(*args)print list(starmap(lambda x,y,z:x+y+z, values))# 与上述等价, starmap更加灵活一些print list(map(lambda x:sum(x), values))
[6, 15, 24][6, 15, 24]
# 把一个迭代器分为n个迭代器,返回一个元组,默认是两个, 可以认为是迭代器的复制r = xrange(3)r1, r2, r3 = tee(r, 3)print list(r1), list(r2), list(r3)
[0, 1, 2] [0, 1, 2] [0, 1, 2]

组合

# 创建一个迭代器,生成表示item1,item2的笛卡尔积的元组# repeat是一个关键字参数, 指定序列的重复次数l1 = xrange(3)l2 = "aac"print list(product(l1, l2))print list(product(l1, repeat = 2))# product(l1, repeat = 3)等价于product(l1, l1, l1)print list(product(l1, repeat = 3)) == list(product(l1, l1, l1))
[(0, 'a'), (0, 'a'), (0, 'c'), (1, 'a'), (1, 'a'), (1, 'c'), (2, 'a'), (2, 'a'), (2, 'c')][(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]True
# 排列, r表示排列的长度, 默认与输入序列相同长度, 不会去重print list(permutations(xrange(3)))print list(permutations(xrange(3), r = 2))print list(permutations((1,1), r = 2))
[(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)][(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)][(1, 1), (1, 1)]
# 返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序# 即index = 0->1,2, 1->2..., n-1->nprint list(combinations("aab", r = 2))# 即index = m->x, x∈[0-n] & x!=m, m∈[0, n]print list(permutations("aab", r = 2))# 即index = 0->0,1,2, 1->1,2..., n-1->n-1,nprint list(combinations_with_replacement("aab", 2))
[('a', 'a'), ('a', 'b'), ('a', 'b')][('a', 'a'), ('a', 'b'), ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'a')][('a', 'a'), ('a', 'a'), ('a', 'b'), ('a', 'a'), ('a', 'b'), ('b', 'b')]

参考网址http://www.wklken.me/posts/2013/08/20/python-extra-itertools.html