itertools — 为高效循环创建迭代器的函数

作者:vk
链接:https://0vk.top/zh-hans/article/details/43/
来源:爱尚购icon-default.png?t=M4ADhttp://0vk.top

 所谓迭代器,就是一堆东西在那里放着,只有构造数据的规则没有具体数据。

比如老师提出问题:小明同学请你从0数到100,这时候你的脑袋里已经有了一个迭代器了。你的大脑里已经生成一个构造这100个数字的迭代器,但是这些数并没有被写在黑板上。

下一秒老师让你写在黑板上,这时候你的大脑开始遍历那个迭代器,而你的手把它们依次写在(打印在)了黑板上。

       很多时候我们可以自己构造一个迭代器处理问题,但是很多实际情况我们自己构造的又臭又长,非常不优雅,不高效。

itertools就主要用来创建迭代器的内置库,其中函数主要可以分为三类,分别是无限迭代器有限迭代器组合迭代器

使用前请先

import itertools

无限迭代器

count

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

 接收两个可选整形参数,第一个指定了迭代开始的值,第二个指定了迭代的步长。此外,start参数默认为0,step参数默认为1,可以根据需要来把这两个指定为其它值,或者使用默认参数。

for i in itertools.count(0,2):
    print(i)
    if i>10: 
        break


#结果
0
2
4
6
8
10
12

cycle

itertools.cycle(iterable)

 使迭代器从可迭代对象返回元素并保存每个元素的副本。 当迭代用完时,从保存的副本中返回元素。 无限重复。

for i in itertools.cycle("abcd"):
    print(i)    
    
#结果一直循环打印abcd,不会自己停
a
b
c
d
a
b
c
d
a
b
c
d
.
.
.

repeat

itertools.repeat(object[, times])制作一个迭代器,一遍又一遍地返回 object。 无限期运行,除非指定了 times 参数。 

for i in itertools.repeat("abcd",5):
    print(i)
    #结果
abcd
abcd
abcd
abcd
abcd

repeat 的常见用途是向 map 或 zip 提供常量值流:

print(list(map(pow, range(10), itertools.repeat(2))))
#结果
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

这一坨是什么意思呢?

首先最外层的list是为了将map造出来的对象转化为列表的。map函数接受两种参数:map(function, iterable, ...),第一个参数是一个函数,指定计算规则,上述例子使用内置的函数pow用来计算x 的 y 次方。

第二个参数是可被遍历的对象。比如

print(list(map(pow,[1,2],[2,2])))
#结果
[1, 4]

map会将第一个列表中的元素依次拿出来交给pow,同时把第二个列表中的一堆2也拿出来交给pow,所以最后就是对第一个列表里的元素计算平方。

repeat通常用的场景就是提供常量流,给多了没关系的,下面的依旧会打印[1,4]

print(list(map(pow,[1,2],[2,2,2,2,2])))
#结果
[1, 4]

组合迭代器

组合操作包括排列,组合,笛卡儿积,或者一些离散元素的选择,组合迭代器就是产生这样序列的迭代器。

product

itertools.product(*iterablesrepeat=1)输入迭代的笛卡尔积。

大致相当于生成器表达式中的嵌套 for 循环。 例如,product(A, B) 返回与 ((x,y) for x in A for y in B) 相同。

嵌套循环就像里程表一样循环,最右边的元素在每次迭代中前进。 此模式创建字典顺序,以便如果输入的可迭代对象已排序,则产品元组按排序顺序发出。

要计算可迭代对象与自身的乘积,请使用可选的 repeat 关键字参数指定重复次数。

 例如,product(A, repeat=4) 与 product(A, A, A, A) 的含义相同。

for i in itertools.product('abc','xyz'):
    print(i)

    #结果
('a', 'x')
('a', 'y')
('a', 'z')
('b', 'x')
('b', 'y')
('b', 'z')
('c', 'x')
('c', 'y')
('c', 'z')

##############################

for i in itertools.product('ab','xy',repeat=2): # =('ab','xy','ab','xy')
    print(i)
  
    #结果
('a', 'x', 'a', 'x')
('a', 'x', 'a', 'y')
('a', 'x', 'b', 'x')
('a', 'x', 'b', 'y')
('a', 'y', 'a', 'x')
('a', 'y', 'a', 'y')
('a', 'y', 'b', 'x')
('a', 'y', 'b', 'y')
('b', 'x', 'a', 'x')
('b', 'x', 'a', 'y')
('b', 'x', 'b', 'x')
('b', 'x', 'b', 'y')
('b', 'y', 'a', 'x')
('b', 'y', 'a', 'y')
('b', 'y', 'b', 'x')
('b', 'y', 'b', 'y')

permutations

itertools.permutations(iterable,r=None)

返回的是可迭代元素中的一个排列组合,并且是按顺序返回的,且不包含重复的结果。

import itertools
for i in itertools.permutations('abc'):
    print(i)

#结果
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')

当然,第 2 个参数默认为None,它表示的是返回元组(tuple) 的长度,我们来尝试一下传入第二个参数。

import itertools
for i in itertools.permutations('abc',2):
    print(i)

#结果
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')

combinations

itertools.combinations(iterabler)

返回的是可迭代对象所有的长度为 r 的子序列。permutation 返回的是排列,而 combinations 返回的是组合。

import itertools
for i in itertools.combinations('1234',2):
    print(i)

('1', '2')
('1', '3')
('1', '4')
('2', '3')
('2', '4')
('3', '4')

combinations_with_replacement

itertools.combinations_with_replacement(iterabler)

返回一个可与自身重复的元素组合,用法类似于 combinations 。

import itertools
for i in itertools.combinations_with_replacement('1234',2):
    print(i)

#结果
('1', '1')
('1', '2')
('1', '3')
('1', '4')
('2', '2')
('2', '3')
('2', '4')
('3', '3')
('3', '4')
('4', '4')

有限迭代器

chain

itertools.chain(*iterables)

制作一个迭代器,从第一个迭代器返回元素,直到它耗尽,然后继续下一个迭代器,直到所有迭代器都耗尽。 用于将连续序列视为单个序列

for i in itertools.chain('abc','def'):
    print(i)

    #结果
a
b
c
d
e
f

groupby

itertools.groupby(iterablekey=None)

groupby()的作用就是把可迭代对象中相邻的重复元素挑出来放一起,举个例子:

for key, group in groupby('AAABBBCCAAA'):
    print(key, list(group))
    #结果
        
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']

实际上挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key。如果我们要忽略大小写分组,就可以让元素'A'和'a'都返回相同的key:

for key, group in groupby('AaaBBbcCAAa', lambda c: c.upper()):
    print(key, list(group))

经过函数后a变成了A,所以它们仍然是在一组的

accumulate

itertools.accumulate(iterable[, func*initial=None])

创建一个迭代器,返回累积的总和,或其他二元函数的累积结果(通过可选的 func 参数指定)。

如果提供了 func,它应该是一个有两个参数的函数。 输入 iterable 的元素可以是任何可以作为 func 参数接受的类型。 (例如,对于加法的默认操作,元素可以是任何可加类型,包括 Decimal 或 Fraction。)

通常,元素输出的数量与输入迭代匹配。 但是,如果提供关键字参数 initial,则累积以 initial 值开始,因此输出比输入可迭代元素多一个元素。

for i in itertools.accumulate([0,1,0,1,1,2,3,5]):
    print(i)
#结果
0
1
1
2
3
5
8
13

函数默认是加法操作,a,a+b,a+b+c,a+b+c+d+e ···

也可以自己指定函数

 

for i in itertools.accumulate([2,1,4,3,5],max):
    print(i)
    
    #结果
2
2
4
4
5

假设&是比大小的意思那么上面程序的结果就是比大小后的最大值

2,  2&1 ,  2&1&4 , 2&1&4&3,  2&1&4&3&5  

 单词数:499字符数:4438

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.vk

你的鼓励就像月亮,照亮了在黑暗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值