itertools拼装迭代器与生成器

本文介绍了Python内置itertools库的三大功能:连接迭代器、过滤元素与合成新元素,包括chain、repeat、cycle、tee、zip_longest等实用函数,帮助读者实现高效简洁的编程技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python内置的标准库itertools有很多函数,可以用来安排迭代器之间的交互关系,这使得在纯Python中有可能创建简洁又高效的专用工具,比如排列组合

今天我们将这些函数分为三类,来感受一下吧。

# 先引入该内置标准库
import itertools

1. 连接多个迭代器

itertools模块中有一些函数可以把多个迭代器连成一个使用。

chain可以把多个迭代器从头到尾连成一个迭代器

it = itertools.chain([1,2,3],[4,5,6])
list(it)
[1, 2, 3, 4, 5, 6]

repeat:可以制作一个不停输出某个值的迭代器,通过设置第二个参数指定该迭代器最多输出几次

it = itertools.repeat('hello',3)
list(it)
['hello', 'hello', 'hello']

cycle可以制作一个循环输出某段内容之中的各项元素的迭代器,可以通过间接方式获取我们需要的值

it = itertools.cycle([1,2])
# 只需要10个元素的列表
result = [next(it) for _ in range(10)]
result
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2]

tee可以让一个迭代器分列成多个平行的迭代器,具体个数通过设置第二个参数指定

it1,it2,it3 = itertools.tee(['可以叫我才哥','才哥'], 3)
print(list(it1),list(it2),list(it3))
['可以叫我才哥', '才哥'] ['可以叫我才哥', '才哥'] ['可以叫我才哥', '才哥']

zip_longest:类似python内置函数zip,区别在于如果源迭代器的长度不一致,可以通过设置参数fillvalue的值来填补提前耗尽的那些迭代器留下的空缺

keys = ['one','two','three']
values = [1,2]

normal = list(zip(keys, values))
print('zip:'.ljust(20),normal)

it = itertools.zip_longest(keys,values,fillvalue='缺失值')
print('zip_longest:'.ljust(20),list(it))
zip:                 [('one', 1), ('two', 2)]
zip_longest:         [('one', 1), ('two', 2), ('three', '缺失值')]

2. 过滤源迭代器中的元素

itertools模块中有一些函数可以过滤源迭代器中的元素

islice可以在不拷贝数据的前提下,按照下标切割源迭代器。可以只给出切割的终点,或者起点与终点,或者步长等等。

values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

first_five = itertools.islice(values, 5)
print('first_five:'.ljust(20), list(first_five))

middle_odds = itertools.islice(values, 2,8,2)
print('middle_odds:'.ljust(20), list(middle_odds))
first_five:          [1, 2, 3, 4, 5]
middle_odds:         [3, 5, 7]

takewhile从源迭代器获取元素,该元素需要满足测试函数条件

values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 测试函数 需要值满足小于7
less_than_seven = lambda x: x<7
it = itertools.takewhile(less_than_seven, values)
list(it)
[1, 2, 3, 4, 5, 6]

dropwhile和talkwhile相反,从源迭代器删除元素,该元素需要满足测试函数条件,最终保留剩下的元素

values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
less_than_seven = lambda x: x<7
it = itertools.dropwhile(less_than_seven, values)
list(it)
[7, 8, 9, 10]

filterfalse和内置的filter函数相反,它会逐个输出源迭代器不满足测试函数条件的值

values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 测试函数用于获取 偶数
evens = lambda x: x%2 == 0

filter_result = filter(evens, values)
print('filter_result:'.ljust(20), list(filter_result))

filter_false_result = itertools.filterfalse(evens, values)
print('filter_false_result:'.ljust(20), list(filter_false_result))
filter_result:       [2, 4, 6, 8, 10]
filter_false_result: [1, 3, 5, 7, 9]

3. 用源迭代器中的元素合成新元素

itertools模块中有一些函数可以根据源迭代器中的元素合成新的元素,排列组合功能!

accumulate:从源迭代器中取出一个元素,并把已经累计的结果与这个元素一起传给表示累加逻辑的函数,然后输出累计值。

values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 求列表累计值(逐个累加输出)
sum_reduce = itertools.accumulate(values)
print('sum_reduce:'.ljust(20), list(sum_reduce))

# 函数的定义是2个值相加,输出该值对20取模(除以20后的余数)
def sum_modulo_20(first, second):
    output = first + second
    return output % 20

modulo_reduce = itertools.accumulate(values, sum_modulo_20)
print('modulo_reduce:'.ljust(20), list(modulo_reduce))
sum_reduce:          [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
modulo_reduce:       [1, 3, 6, 10, 15, 1, 8, 16, 5, 15]

product从一个或多个源迭代器中获取元素,然后计算笛卡尔积

single = itertools.product([1,2], repeat=2)
print('single:'.ljust(20), list(single))

multiple = itertools.product([1,2], ['a','b'])
print('multiple:'.ljust(20), list(multiple))
single:              [(1, 1), (1, 2), (2, 1), (2, 2)]
multiple:            [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

permutations对于源迭代器中的元素,逐个输出有其中N个元素组成的有序排列(元素相同但顺序不同,则算不同的排列)

it = itertools.permutations([1,2,3,4],2)
list(it)
[(1, 2),
 (1, 3),
 (1, 4),
 (2, 1),
 (2, 3),
 (2, 4),
 (3, 1),
 (3, 2),
 (3, 4),
 (4, 1),
 (4, 2),
 (4, 3)]

combinations对于源迭代器中的元素,逐个输出有其中N个元素组成的无序排列(元素相同但顺序不同,也算同一个排列)

it = itertools.combinations([1,2,3,4],2)
list(it)
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

combinations_with_replacement:和combinations类似,区别在于它允许同一个元素在组合中出现多次,有放回的排列组合

it = itertools.combinations_with_replacement([1,2,3,4],2)
list(it)
[(1, 1),
 (1, 2),
 (1, 3),
 (1, 4),
 (2, 2),
 (2, 3),
 (2, 4),
 (3, 3),
 (3, 4),
 (4, 4)]

以上就是本次全部内容,关于itertools模块更多的使用技巧,大家可以查阅官方文档:

https://docs.python.org/zh-cn/3.8/library/itertools.html
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值