作者:才哥
☆
大家好,我是才哥。
Python内置的标准库itertools
有很多函数,可以用来安排迭代器之间的交互关系,这使得在纯Python中有可能创建简洁又高效的专用工具,比如排列组合!
今天我们将这些函数分为三类,来感受一下吧。
# 先引入该内置标准库
import itertools
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', '缺失值')]
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]
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