41 Python itertools

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:
        break
print 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]

# 把迭代器中相邻的相同元素挑出来放在一起
# 挑选规则是通过函数完成,两个元素的函数返回值相同,两个元素就视为相同, 函数返回值作为key
for 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))
# 等价于compress
print 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->n
print 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,n
print 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值