本文目录

一、模块概述

二、组合生成器

2.1 product

2.2 permutations

2.3 combinations

2.4 combinations_with_replacement

三、无限迭代器

3.1 count

3.2 cycle

3.3 repeat

四、有限迭代器

4.1 accumulate

4.2 chain

4.3 chain.from_iterable

4.4 compress

4.5 dropwhile

4.6 filterfalse

4.7 groupby

4.8 islice

4.9 starmap

4.10 takewhile

4.11 tee

4.12 zip_longest

五、总结

一、模块概述

Functional tools for creating and using iterators,为高效循环而创建迭代器的函数。本模块标准化了一个快速、高效利用内存的核心工具集,这些工具本身或组合都很有用。它们一起形成了“迭代器代数”,这使得在纯Python中有可能创建简洁又高效的专用工具。

permutations函数可以求序列的排列,combinations函数可以求序列的组合除了这两个函数外,itertools还有相当多的功能,它主要是提供迭代类的操作。

迭代器的特点是:惰性求值(Lazy evaluation),即只有当迭代至某个值时,它才会被计算,这个特点使得迭代器特别适合于遍历大文件或无限集合等,因为我们不用一次性将它们存储在内存中。itertools 模块提供的迭代器函数有以下几种类型:

组合生成器:序列的排列、组合,求序列的笛卡儿积等,比如product可以生成两个序列的笛卡尔积;

无限迭代器:生成一个无限序列,比如count函数能生成自然数序列 1, 2, 3, 4, ...

有限迭代器:接收一个或多个序列(sequence)作为参数,进行组合、分组和过滤等,比如chain函数,能组合多个序列

print(dir(itertools))
['__doc__', '__loader__', '__name__', '__package__', '__spec__','_grouper', '_tee', '_tee_dataobject', 'accumulate', 'chain', 'combinations', 'combinations_with_replacement', 'compress', 'count', 'cycle', 'dropwhile', 'filterfalse', 'groupby', 'islice', 'permutations', 'product', 'repeat', 'starmap', 'takewhile', 'tee', 'zip_longest']

总之该模块为Python为创建自定义迭代器提供了非常好用的模块——itertools。由itertools提供的工具通常都很快速而且节省内存。你可以利用这些组成部分去创建自己独有的迭代器以完成高效的循环

官方参考文档:https://docs.python.org/zh-cn/3/library/itertools.html

二、排列组合迭代器

迭代器

实参

结果

product()

p, q, ... [repeat=1]

笛卡尔积,相当于嵌套的for循环

permutations()

p[, r]

长度r元组,所有可能的排列,无重复元素

combinations()

p, r

长度r元组,有序,无重复元素

combinations_with_replacement()

p, r

长度r元组,有序,元素可重复

例子

结果

product('ABCD', repeat=2)

AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD

permutations('ABCD', 2)

AB AC AD BA BC BD CA CB CD DA DB DC

combinations('ABCD', 2)

AB AC AD BC BD CD

combinations_with_replacement('ABCD', 2)

AA AB AC AD BB BC BD CC CD DD

2.1 product

作用:用于求多个可迭代对象的笛卡尔积,它跟嵌套的 for 循环等价

语法:itertools.product(iter1, iter2, ... iterN, [repeat=1])

for each in itertools.product('ABCD', 'XY'):print(each)
('A', 'X')
('A', 'Y')
('B', 'X')
('B', 'Y')
('C', 'X')
('C', 'Y')
('D', 'X')
('D', 'Y')for each in itertools.product('abc', repeat=2):print (each)
('a', 'a')
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'b')
('b', 'c')
('c', 'a')
('c', 'b')
('c', 'c')

2.2 permutations

作用:返回长度为r的排列

语法:itertools.permutations(iteravle[,r])

  • iterable: 可迭代对象

  • r: 关键字参数, 新元素的长度, 默认为 None, 即为新元素的长度就是元素个数

将 iterable 中的元素以长度为 r 进行排列。每个排列组合生成一个元组并添加到新迭代器中。排列时,排列顺序是按照 iterable 中元素的顺序进行的。因此,未排序的 iterable 和已排序的 iterable 排列后的结果是不同的。

若 iterable 中有相同值的元素,但是它们的位置是不同的,排列时也就会会认为它们是不同的。注意: 排列即为数学上的排列,从 n 个元素中取出 m 个元素的无重复排列或直线排列。

for each in itertools.permutations('abc', 2):print (each)
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')

2.3 combinations

作用:返回指定长度的组合

语法: itertools.combinations(iterable, r)

iterable: 可迭代对象
r: 新元素的长度
for each in itertools.combinations('abc', 2):print (each)
('a', 'b')
('a', 'c')
('b', 'c')
将 iterable 中的元素以长度为 r 进行组合。每个排列组合生成一个元组并添加到新迭代器中。与 permutations() 函数基本一致,但是 combinations() 函数会过滤掉元素值一致的元组。
'''相比于排列,组合会筛选掉元素值一样的元组'''
list(itertools.combinations('ABC', 2))
[('A', 'B'), ('A', 'C'), ('B', 'C')]'''排列对照组'''
list(itertools.permutations('ABC', 2))
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

2.4 combinations_with_replacement

作用:返回指定长度的组合,组合内元素可重复

语法:itertools.combinations_with_replacement(iterable, r)

  • iterable: 可迭代对象

  • r: 关键字参数, 新元素的长度, 默认为 None, 即为新元素的长度就是元素个数

for each in itertools.combinations_with_replacement('abc', 2):print (each)
('a', 'a')
('a', 'b')
('a', 'c')
('b', 'b')
('b', 'c')
('c', 'c')

三、无限迭代器

有三个无限迭代器,当你使用它们的时候,你要知道何时去跳出这个循环,不然你将陷入无限循环之中,在生产数字或者遍历事先不知道长度的数据时非常有用。

迭代器

实参

结果

示例

count()

start, [step]

start,start+step,start+2*step, ...

count(10) --> 10 11 12 13 14 ...

cycle()

p

p0, p1, ... plast, p0, p1, ...

cycle('ABCD') --> A B C D A B C D ...

repeat()

elem [,n]

elem, elem, elem, ... 重复无限次或n次

repeat(10, 3) --> 10 10 10

3.1 count()

作用:返回以start开始,step递增的序列,无限递增

语法:itertools.count(start=0,step=1)

for each in itertools.count(start=0, step=2):print (each)
1
2
...
100003'''小应用, 当取到第三个 A 时停止'''
test_str = ''
for i in itertools.cycle('ABC'):test_str += iif test_str.count('A') >= 3:break
print(test_str)
# ABCABCA

3.2 cycle()

作用:将迭代器进行无限迭代

语法:itertools.cycle(iterable)

for each in itertools.cycle('ab'):print(each)
a
b
...
b
a

3.3 repeat()

作用:不停的返回object对象,如果指定了times,则返回times次

语法:itertools.repeat(object,[,times])

for each in itertools.repeat('ab', 2):
print(each)
ab
ab

四、有限迭代器

迭代器

实参

结果

示例

accumulate()

p [,func]

p0, p0+p1, p0+p1+p2, ...

accumulate([1,2,3,4,5]) --> 1 3 6 10 15

chain()

p, q, ...

p0, p1, ... plast, q0, q1, ...

chain('ABC', 'DEF') --> A B C D E F

chain.from_iterable()

iterable

p0, p1, ... plast, q0, q1, ...

chain.from_iterable(['ABC', 'DEF']) --> A B C D E F

compress()

data, selectors

(d[0] if s[0]), (d[1] if s[1]), ...

compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F

dropwhile()

pred, seq

seq[n], seq[n+1], ... 从pred首次真值测试失败开始

dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1

filterfalse()

pred, seq

seq中pred(x)为假值的元素,x是seq中的元素。

filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8

groupby()

iterable[, key]

根据key(v)值分组的迭代器

islice()

seq, [start,] stop [, step]

seq[start:stop:step]中的元素

islice('ABCDEFG', 2, None) --> C D E F G

starmap()

func, seq

func(*seq[0]), func(*seq[1]), ...

starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000

takewhile()

pred, seq

seq[0], seq[1], ..., 直到pred真值测试失败

takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4

tee()

it, n

it1, it2, ... itn 将一个迭代器拆分为n个迭代器

zip_longest()

p, q, ...

(p[0], q[0]), (p[1], q[1]), ...

zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-

4.1 accumulate()

作用:创建一个迭代器,返回累积汇总值或其他双目运算函数的累积结果值(通过可选的 func 参数指定),,若传入 func,则按照 func 中的方法执行。

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

  • iterable: 可迭代对象

  • func: 带有两个参数的函数, 可选参数,func 参数有几种用法。它可以被设为 min() 最终得到一个最小值,或者设为 max() 最终得到一个最大值,或设为 operator.mul() 最终得到一个乘积。摊销表可通过累加利息和支付款项得到。给iterable设置初始值并只将参数 func 设为累加总数可以对一阶 递归关系 建模。

  • initial: 关键字参数, 默认为 None, 若此参数传参, 则此参数作为 iterable 的第一个元素

'''默认情况, 返回累计汇总值'''
list(itertools.accumulate([1, 2, 3, 4, 5]))
[1, 3, 6, 10, 15]'''方法修改为计算累计的乘积'''
import operator #该模块输出一系列对应Python内部操作符的函数
data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
list(itertools.accumulate(data, operator.mul))
[3, 12, 72, 144, 144, 1296, 0, 0, 0, 0]'''方法修改为计算累计的最大值'''
list(itertools.accumulate(data, max))
[3, 4, 6, 6, 6, 9, 9, 9, 9, 9]  # Amortize a 5% loan of 1000 with 4 annual payments of 90
cashflows = [1000, -90, -90, -90, -90]
list(itertools.accumulate(cashflows, lambda bal, pmt: bal*1.05 + pmt))
[1000, 960.0, 918.0, 873.9000000000001, 827.5950000000001]#Chaotic recurrence relation
#https://en.wikipedia.org/wiki/Logistic_map
logistic_map = lambda x, _:  r * x * (1 - x)
r = 3.8
x0 = 0.4
inputs = repeat(x0, 36)     # only the initial value is used
[format(x, '.2f') for x in accumulate(inputs, logistic_map)]
['0.40', '0.91', '0.30', '0.81', '0.60', '0.92', '0.29', '0.79', '0.63','0.88', '0.39', '0.90', '0.33', '0.84', '0.52', '0.95', '0.18', '0.57','0.93', '0.25', '0.71', '0.79', '0.63', '0.88', '0.39', '0.91', '0.32','0.83', '0.54', '0.95', '0.20', '0.60', '0.91', '0.30', '0.80', '0.60']'''在迭代器起始位置添加一个元素, 方法不变, 返回累计汇总值'''
list(itertools.accumulate([1, 2, 3, 4, 5], initial=100))
# [100, 101, 103, 106, 110, 115]'''在迭代器起始位置添加一个元素, 方法修改为计算累计的乘积'''
list(itertools.accumulate([1, 2, 3, 4, 5], lambda x, y: x * y, initial=10))
#[10, 10, 20, 60, 240, 1200]

4.2 chain()

作用:chain 接收多个可迭代对象作为参数,将它们『连接』起来,作为一个新的迭代器返回。

语法:chain(iterable1, iterable2, iterable3, ...)

list(itertools.chain([1, 2, 3], ('A', 'B', 'C'), {'一', '二', '三'}))
[1, 2, 3, 'A', 'B', 'C', '二', '一', '三']
list(itertools.chain( 'ABC', 'DEF'))
['A', 'B', 'C', 'D', 'E', 'F']

4.3 chain.from_iterable

作用:与 itertools.chain() 函数类似,但是参数是一个可迭代对象,将这个可迭代对象中元素一一添加到新迭代器中,如果元素是一个可迭代对象,那么会将这个元素内的元素一一添加到新迭代器中。小编自己的理解就是迭代器降维。

语法:itertools.chain.from_iterable(iterable)

'''将二维迭代器降维'''
temp = itertools.chain.from_iterable(['1', ['2', '3'], ('4', '5')])
print(list(temp))
# ['1', '2', '3', '4', '5']'''只能降一层维度, 三维将至二维'''
temp = itertools.chain.from_iterable(['1', ['2', '3'], ('4', ['5', '6'])])
print(list(temp))
# ['1', '2', '3', '4', ['5', '6']]

PS: 迭代器维度概念可以理解为,整个迭代器中的元素都不是迭代器类型的就是一维,迭代器中的元素有是迭代器的就是二维,迭代器中的元素有是迭代器的,然后这个迭代器中还有元素是迭代器的就是三维,依此类推。

4.4 compress

作用:创建一个迭代器,将 data 中经过 selectors 真值测试为 True 的元素保留。当两个可迭代对象中的某一个到达末尾时执行停止,返回最终结果。

语法:compress(data, selectors)

  • data: 可迭代对象, 包含所需的数据

  • selectors: 可迭代对象, 真值测试数据

for each in itertools.compress('abcd', [1, 0, 1, 0]):print (each)
a
c
'''只判断前三个元素, 并且索引值为 0 和 2 的元素会保留到新迭代器中并返回'''
temp = itertools.compress(['A', 'B', 'C', 'D'], [1, 0, 1])
list(temp)
# ['A', 'C']

4.5 dropwhile

作用:直到predicate为真,就返回iterable剩下的数据, 否则drop掉

语法:itertools.dropwhile(predicate, iterable)

for each in itertools.dropwhile(lambda x: x<5, [2,1,6,8,2,1]):print(each)
6
8
2
1

4.6 filterfalse

作用:创建一个迭代器,仅保留 iterable 中在 predicate 计算中为 False 的元素。如果 predicate 传入的是 None,则相当于传入 bool,意思是做真值测试。

语法:itertools.filterfalse(predicate, iterable)

  • predicate: 只需要一个参数的函数

  • iterable: 可迭代对象

'''元素的值减2小于等于0的为True'''
temp = itertools.filterfalse(lambda x: x - 2 <= 0, [1, 2, 0, 3, 1])
print(list(temp))
# [3]
'''真值测试'''
temp = itertools.filterfalse(None, [1, 2, 0, 3, 1])
print(list(temp))
# [0]

4.7 groupby

作用:返回一组(key,itera),key为iterable的值,itera为等于key的所有项

语法:itertools.groupby(iterable[,key])

for key, vale in itertools.groupby('aabbbc'):print( key, list(vale))
a ['a', 'a']
b ['b', 'b', 'b']
c ['c']

4.8 islice

作用:相当于迭代器方式的切片操作

语法:itertools.islice(iterable, start,stop[,step])

for each in itertools.islice('abcdefg', 1, 4, 2):print(each)
b
d

4.9 starmap()

作用:返回function(iter)的值,iter为iterable的元素

语法:itertools.starmap(function,iterable)

for each in itertools.starmap(lambda x, y: x * y, [(1, 2), (3, 4)]):print(each)
2
12

4.10 takewhile()

作用:创建一个迭代器,将 iterable 中的元素当作 function 的参数计算,与 dropwhile() 函数恰恰相反,当结果的布尔值为 True 时,其元素添加到新迭代器中, 直到有元素的计算结果为 False 时,此元素与之后的元素全部抛弃。

语法:itertools.takewhile(predicate,iterable)

for each in itertools.takewhile(lambda x: x < 5, [1, 3, 5, 6]):
print(each)
1
3

4.11 tee

作用:从一个可迭代对象中分裂出 n 个独立的可迭代对象并返回。

语法:itertools.tee(iterable, n=2)

for i in itertools.tee([1, 2, 3, 4, 5, 6], 2):print(list(i))
# [1, 2, 3, 4, 5, 6]
# [1, 2, 3, 4, 5, 6]

4.12 zip_longest

作用:创建一个迭代器,从所有传入的可迭代对象中抽取一个元素,将它们组合成一个元组,然后添加到迭代器中。

语法:itertools.zip_longest(*iterables, fillvalue=None)

  • iterables: 一个或多个可迭代对象

  • fillvalue: 关键字参数, 填充值, 默认为 None

list(itertools.zip_longest('xyz', '123456', '小伍哥', fillvalue='*'))
[('x', '1', '小'),('y', '2', '伍'),('z', '3', '哥'),('*', '4', '*'),('*', '5', '*'),('*', '6', '*')]

五、总   结

迭代器(生成器)在Python中是一种很常用也很好用的数据结构,比起列表(list)来说,迭代器最大的优势就是延迟计算,按需使用,从而提高开发体验和运行效率,以至于在Python 3中map,filter等操作返回的不再是列表而是迭代器。而通过iter函数把列表对象转化为迭代器对象又有点多此一举,这时候我们今天的主角itertools就该上场了。

itertools中的函数大多是返回各种迭代器对象,其中很多函数的作用我们平时要写很多代码才能达到,而在运行效率上反而更低,大概就总结到这里,不过Python的各种语言特性和库还是要多用才能熟练,最终达到随手拈来的程度。

往期精彩回顾适合初学者入门人工智能的路线及资料下载机器学习及深度学习笔记等资料打印机器学习在线手册深度学习笔记专辑《统计学习方法》的代码复现专辑
AI基础下载机器学习的数学基础专辑
本站qq群704220115,加入微信群请扫码:

【Python基础】Python中的高效迭代库itertools,排列组合随便求相关推荐

  1. Python基础-Python基础使用

    Python基础-Python基础使用 1.Python解释器 在Python文件的开头加入以下代码就制定了解释器. #!/usr/bin/env python # _*_ coding:utf-8 ...

  2. python基础 python函数 函数概念 函数的多种参数 多种调用参数 装包 解包 函数代码块 函数的返回值

    python基础 python函数 函数概念 函数的多种参数 多种调用参数 装包 解包 函数代码块 函数的返回值 一 .函数概念 函数是根据需要,将代码打包为代码块, 每一个代码块就可以封装为一个函数 ...

  3. python基础===Python 代码优化常见技巧

    Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 8 ...

  4. Python基础--Python简介和入门

    ☞写在前面 在说Python之前,我想先说一下自己为什么要学Python,我本人之前也了解过Python,但没有深入学习.之前接触的语言都是Java,也写过一些Java自动化用例,对Java语言只能说 ...

  5. Python 基础 —— Python程序员常犯的那些错误

    1. 迭代时修改一个列表 删除列表中的奇数 >>>numbers = [i for i in range(10)] >>>numbers [0, 1, 2, 3, ...

  6. python自带性能强悍的标准库 itertools

    可迭代对象就像密闭容器里的水,有货倒不出 itertools是python内置的标准模块,提供了很多简洁又高效的专用功能,使用得当能够极大的简化代码行数,同时所有方法都是实现了生成器函数,这就意味着极 ...

  7. 每日整理Python基础——python教程入门学习

    01_Linux基础 1.操作系统的作用? 操作系统是配置在计算机硬件上的第一层软件,主要作用是管理好硬件设备. 2.Linux中根目录和家目录分别用什么表示? /表示根目录.~表示家目录 3.Lin ...

  8. Python 基础 — Python 简介

    前言 未来是数据的世界,而 python 是一门可以高效简洁处理数据的语言,博主打算花一些时间完成 python 学习的从 0 到 1.以此相关系列博客作为一个记录. 1. Python 简介 Pyt ...

  9. python基础-python的字符串内建函数

    python基础-字符串内建函数 文章目录 python基础-字符串内建函数 前言 常用的函数 1.center() 2.count() 3.endswith() 4.startswith() 5.s ...

最新文章

  1. 怎样从0一步一步搭建用户激励体系
  2. extjs 页面打开时表格自动加载后台传来的json数据
  3. ASP.NET Core 3.0 gRPC 双向流
  4. 微软Windows Mobile智能手机GPRS上网设置教程(转)
  5. Tensorflow框架:卷积神经网络实战--Cifar训练集
  6. Linux编程简介——VI
  7. Python排序算法总结
  8. 仿QQ打开网址显示的当前网页非官方页面
  9. MTK 驱动(65)---Android 多点触摸协议(Multi-touch Protocol)
  10. Python密码存储器
  11. 拓端tecdat|R语言实现有限混合模型建模分析
  12. 电气技术与计算机技术结合,探析计算机与电气自动化技术有机结合.doc
  13. win Server 2012 R2 密钥
  14. IXI数据预处理 + Linux + freesurfer
  15. 斐讯n1安装linux安装微信,斐讯N1打造小型NAS六之armbian安装aria2
  16. 如何在简中版 MathType 安装过程中,就能输入产品密匙?
  17. 【CSS3】渐变背景
  18. openfire安装配置
  19. PS网页设计教程XVI——在PS中创建一个摩登实验室风格的网页设计
  20. ARM-translation table walk

热门文章

  1. php模拟socket一次连接,多次发送数据的实现
  2. vue中computed(计算属性)和watch在实现父子组件props同步时的实际区分
  3. 数据库出现的bug原因以及解决方法
  4. 【2017-02-18】C#基础 - 定义变量,输入输出(最基础的编程,以及灵活多变的编写思维)...
  5. netty源码分析之一:server的启动
  6. js String方法集合
  7. CodeForces 474.D Flowers
  8. The method setOnClickListener(View.OnClickListener) in the type View is not applicable
  9. GridView实战二:使用ObjectDataSource数据源控件
  10. Silverlight Tips(1)