查看原文
其他

itertools拼装迭代器与生成器

才哥的学习笔记 可以叫我才哥 2021-10-08



关注可以叫我才哥,学习分享数据之美

我们的第80篇原创

作者:才哥


大家好,我是才哥。

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

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

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

1. 连接多个迭代器

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

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

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

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
[1212121212]

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 = [12345678910]

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:          [12345]
middle_odds:         [357]

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

values = [12345678910]
# 测试函数 需要值满足小于7
less_than_seven = lambda x: x<7
it = itertools.takewhile(less_than_seven, values)
list(it)
[123456]

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

values = [12345678910]
less_than_seven = lambda x: x<7
it = itertools.dropwhile(less_than_seven, values)
list(it)
[78910]

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

values = [12345678910]
# 测试函数用于获取 偶数
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:       [246810]
filter_false_result: [13579]

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

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

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

values = [12345678910]
# 求列表累计值(逐个累加输出)
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:          [13610152128364555]
modulo_reduce:       [13610151816515]

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:              [(11), (12), (21), (22)]
multiple:            [(1'a'), (1'b'), (2'a'), (2'b')]

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

it = itertools.permutations([1,2,3,4],2)
list(it)
[(12),
 (13),
 (14),
 (21),
 (23),
 (24),
 (31),
 (32),
 (34),
 (41),
 (42),
 (43)]

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

it = itertools.combinations([1,2,3,4],2)
list(it)
[(12), (13), (14), (23), (24), (34)]

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

it = itertools.combinations_with_replacement([1,2,3,4],2)
list(it)
[(11),
 (12),
 (13),
 (14),
 (22),
 (23),
 (24),
 (33),
 (34),
 (44)]

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

https://docs.python.org/zh-cn/3.8/library/itertools.html

-->推荐阅读<--

『小知识』Python自动安装第三方库的小技巧

『小知识』Python输出还可以这么花里胡哨

『数据分析』使用python进行同期群分析

『网络爬虫』《速度与激情》系列中最拉胯的一部

『数据分析』pandas计算连续行为天数的几种思路

『福利』14张数据科学速查表+28本Python电子书

『网络爬虫』手把手教你扒一扒贝壳网成交房源数据

『数据分析』浅谈游戏运营中LTV的计算

『数据分析』使用Python计算RFM用户价值模

扫码添加作者好友,一起组队学习

微信号

gdc2918

微信公众号

可以叫我才哥

分享、在看与点赞

爱你一万年~

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存