python 超好用的迭代兵器库itertools,十八般兵器哪18般?

简介: python 超好用的迭代兵器库itertools,十八般兵器哪18般?

知识点


在古典小说和传统评话中,常说武艺高强的人是“十八般武艺样样精通”,这十八般武艺是指使用“十八般兵器”的功夫和技能。哪十八般呢?


十八般兵器在武术界中最普遍的说法是:刀、枪、剑、戟、斧、钺、钩、叉、鞭、锏、锤、抓、镗、棍、槊、棒、拐、流星。


20210902105901947.png



汉武于元封四年(公元前107),经过严格的挑选和整理,筛选出18种类型的兵器:矛、镗、刀、戈、槊、鞭、锏、剑、锤、抓、戟、弓、钺、斧、牌、棍、枪、叉。


三国时代,著名的兵器鉴别家吕虔,根据兵器的特点,对汉武帝钦定的“十八般兵器”重新排列为九长九短。九长:戈、矛、戟、槊、镗、钺、棍、枪、叉;九短:斧、戈、牌、箭、鞭、剑、锏、锤、抓。

明代《五杂俎》和清代《坚集》两书所载,“十八般兵器”为弓、弩、枪、刀、剑、矛、盾、斧、钺、戟、黄、锏、挝、殳(棍)、叉、耙头、锦绳套索、白打(拳术)。后人称其为“小十八般”。




迭代器


迭代器的最大优势就是延迟计算按需使用,节省内存空间、提高运行效率。


迭代工具库 itertools 中共有18个函数,恰好似“迭代界”的十八般兵器,掌握了这些功夫和技能也可以说是“十八般武艺样样精通”!:

>>> import itertools
>>> tools = [func for func in dir(itertools) if func[0]>='a']
>>> len(tools)
18
>>> tools
['accumulate', 'chain', 'combinations', 'combinations_with_replacement', 'compress', 
'count', 'cycle', 'dropwhile', 'filterfalse', 'groupby', 'islice', 'permutations', 
'product', 'repeat', 'starmap', 'takewhile', 'tee', 'zip_longest']



1. 累加器 accumulate

>>> import itertools as it
>>> it.accumulate(range(1,11))
<itertools.accumulate object at 0x0A0C9988>
>>> list(it.accumulate(range(1,11)))
[1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
>>> list(it.accumulate([1]*10))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> 
>>> L = [1]*10
>>> list(it.accumulate(L))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> L = list(it.accumulate(L))
>>> list(it.accumulate(L))
[1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
>>> 


1乘2乘3...一直乘到n有阶乘运算 n! ,但1加2加3...一直加到n,一般都没有定义“累和”运算,还需循环来计算。现在有了这个函数可以代替用用的,比如1加到100:

1. >>> list(it.accumulate(range(1+100)))[-1]
2. 5050
3. >>>


不用此库函数的代码实现:

>>> a = [1 for _ in range(10)]
>>> a
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
>>> for i,n in enumerate(a):
  if i:a[i] += a[i-1]  # 或 if i+1<len(a):a[i+1] += n
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> for i in range(1,len(a)):
  a[i] += a[i-1] # 这样原始的比较简洁
>>> a
[1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
>>> 


还有另外两个参数 func 和  initial,可以完成其它自定义运算:

>>> list(it.accumulate([1,2,3,4],lambda x,y:x+y))
[1, 3, 6, 10]
>>> list(it.accumulate([1,2,3,4],lambda x,y:x*y))
[1, 2, 6, 24]
>>> list(it.accumulate([1,2,3,4],lambda x,y:x-y))
[1, -1, -4, -8]
>>> list(it.accumulate([1,2,3,4],lambda x,y:y-x))
[1, 1, 2, 2]
>>> import operator
>>> list(it.accumulate([1,2,3,4],operator.add))
[1, 3, 6, 10]
>>> list(it.accumulate([1,2,3,4],operator.sub))
[1, -1, -4, -8]
>>> list(it.accumulate([1,2,3,4],operator.mul))
[1, 2, 6, 24]
>>> list(it.accumulate([1,2,3,4], operator.mul, initial=2))
[2, 2, 4, 12, 48]
>>> 



2. 连接器 chain

连接多个迭代器,或其它可迭代对象

>>> import itertools as it
>>> it.chain(range(3),[3,4,5],{6,7},(i for i in range(8,11)))
<itertools.chain object at 0x0A0BF3B8>
>>> list(it.chain(range(4),[4,5],{6,7},(i for i in range(8,11))))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> 



3. 组合器 combinations

from itertools import combinations as comb
>>> comb1 = comb(range(4), 3)
>>> list(comb1)
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
>>> comb2 = comb(range(1,6), 3)
>>> list(comb2)
[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5),
 (1, 4, 5), (2, 3, 4), (2, 3, 5), (2, 4, 5), (3, 4, 5)]
>>> comb3 = comb(range(1,6), 4)
>>> list(comb3)
[(1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5)]
>>> 


4. 可重复组合器 combinations_with_replacement

>>> from itertools import combinations_with_replacement as Comb2
>>> comb1 = Comb2(range(4), 3)
>>> list(comb1)
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 1), (0, 1, 2), (0, 1, 3),
 (0, 2, 2), (0, 2, 3), (0, 3, 3), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 2),
 (1, 2, 3), (1, 3, 3), (2, 2, 2), (2, 2, 3), (2, 3, 3), (3, 3, 3)]
>>> comb2 = Comb2(range(1,6), 3)
>>> list(comb2)
[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 1, 5), (1, 2, 2), (1, 2, 3),
 (1, 2, 4), (1, 2, 5), (1, 3, 3), (1, 3, 4), (1, 3, 5), (1, 4, 4), (1, 4, 5),
 (1, 5, 5), (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 2, 5), (2, 3, 3), (2, 3, 4),
 (2, 3, 5), (2, 4, 4), (2, 4, 5), (2, 5, 5), (3, 3, 3), (3, 3, 4), (3, 3, 5),
 (3, 4, 4), (3, 4, 5), (3, 5, 5), (4, 4, 4), (4, 4, 5), (4, 5, 5), (5, 5, 5)]
>>> 


5. 排列器 permutations

>>> import itertools as it
>>> list(it.permutations([1,2,3]))
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
>>> # 数字1、2、3能组成哪些三位数?
>>> [i[0]*100+i[1]*10+i[2] for i in it.permutations([1,2,3])]
[123, 132, 213, 231, 312, 321]
>>> 


6. 压缩器 compress

按照真值表来精简迭代器,筛选出部分值

1. >>> import itertools as it
2. >>> i = it.compress(range(6), (1,1,0,0,1,0))
3. >>> list(i)
4. [0, 1, 4]
5. >>>


7. 切片器 islice

>>> import itertools as it
>>> islice = it.islice(range(100),0,9,2)
>>> list(islice)
[0, 2, 4, 6, 8]
>>> iSlice = it.islice(range(1,100),0,9,2)
>>> list(iSlice)
[1, 3, 5, 7, 9]
>>> # 可以不指定起始和步长,直接指定个数
>>> list(it.islice(range(1,100),10))
[1, 11, 21, 31, 41, 51, 61, 71, 81, 91]
>>> 


8. 计数器 count

因为生成器只提供说法不是数据集,直接用 list(count1)会死循环的,可以用islice()指定一下个数。

>>> import itertools as it
>>> count1 = it.count(start=0,step=3)
>>> list(it.islice(count1,12))
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33]
>>> count2 = it.count(start=100,step=-2)
>>> list(it.islice(count2,10))
[100, 98, 96, 94, 92, 90, 88, 86, 84, 82]
>>> 



9. 循环器 cycle

>>> import itertools as it
>>> list(it.islice(it.cycle('ABC'),10))
['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A']
>>> list(it.islice(it.cycle([1,2,3,4]),10))
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2]
>>> 


10. 重复器 repeat

>>> import itertools as it
>>> list(it.repeat(5,10))
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
>>> list(it.repeat([1,2],5))
[[1, 2], [1, 2], [1, 2], [1, 2], [1, 2]]
>>> 



11. 舍真器 dropwhile

舍弃不满足条件的元素,但当条件不满足即停止筛选

>>> import itertools as it
>>> lst = [1,3,5,2,4,6,10,11,7,8,12,15]
>>> list(it.dropwhile(lambda i:i<9,lst))
[10, 11, 7, 8, 12, 15]
>>> list(it.dropwhile(lambda i:i%2,lst))
[2, 4, 6, 10, 11, 7, 8, 12, 15]
>>> 


12. 留真器 takewhile

留下满足条件的元素,但当条件不满足即停止筛选

>>> import itertools as it
>>> list(it.takewhile(lambda i:i<6, range(10)))
[0, 1, 2, 3, 4, 5]
>>> lst = [1,3,5,2,4,6,10,11,7,8,12,15]
>>> list(it.takewhile(lambda i:i<11,lst))
[1, 3, 5, 2, 4, 6, 10]
>>> list(it.takewhile(lambda i:i%6,lst))
[1, 3, 5, 2, 4]
>>> 


13. 筛假器 filterfalse

舍弃满足条件的所有元素,留下所有不满足条件的

>>> import itertools as it
>>> lst = [1,3,5,2,4,6,10,11,7,8,12,15]
>>> list(it.filterfalse(lambda i:i<9,lst))
[10, 11, 12, 15]
>>> list(it.filterfalse(lambda i:i%2,lst))
[2, 4, 6, 10, 8, 12]
>>> 


14. 分组器 groupby

>>> import itertools as it
>>> group = it.groupby(range(20), lambda i:not 8<i<16)
>>> for i,j in group: print(i,list(j))
True [0, 1, 2, 3, 4, 5, 6, 7, 8]
False [9, 10, 11, 12, 13, 14, 15]
True [16, 17, 18, 19]
>>> 


15. 乘积器 product

>>> import itertools as it
>>> list(it.product('ABC',(1,2)))
[('A', 1), ('A', 2), ('B', 1), ('B', 2), ('C', 1), ('C', 2)]
>>> [''.join(i) for i in list(it.product('ABC','12'))]
['A1', 'A2', 'B1', 'B2', 'C1', 'C2']
>>> [''.join(i) for i in list(it.product('ABCD','123'))]
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3', 'D1', 'D2', 'D3']
>>> # 第二参数: repeat = n , 默认值为1
>>> list(it.product('ABC',[1],repeat=2))
[('A', 1, 'A', 1), ('A', 1, 'B', 1), ('A', 1, 'C', 1),
 ('B', 1, 'A', 1), ('B', 1, 'B', 1), ('B', 1, 'C', 1),
 ('C', 1, 'A', 1), ('C', 1, 'B', 1), ('C', 1, 'C', 1)]
>>> [''.join(i) for i in list(it.product('ABC',repeat=2))]
['AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC']
>>> [''.join(i) for i in list(it.product('ABC','ABC',repeat=2))]
['AAAA', 'AAAB', 'AAAC', 'AABA', 'AABB', 'AABC', 'AACA', 'AACB', 'AACC', 'ABAA',
 'ABAB', 'ABAC', 'ABBA', 'ABBB', 'ABBC', 'ABCA', 'ABCB', 'ABCC', 'ACAA', 'ACAB',
 'ACAC', 'ACBA', 'ACBB', 'ACBC', 'ACCA', 'ACCB', 'ACCC', 'BAAA', 'BAAB', 'BAAC',
 'BABA', 'BABB', 'BABC', 'BACA', 'BACB', 'BACC', 'BBAA', 'BBAB', 'BBAC', 'BBBA',
 'BBBB', 'BBBC', 'BBCA', 'BBCB', 'BBCC', 'BCAA', 'BCAB', 'BCAC', 'BCBA', 'BCBB',
 'BCBC', 'BCCA', 'BCCB', 'BCCC', 'CAAA', 'CAAB', 'CAAC', 'CABA', 'CABB', 'CABC',
 'CACA', 'CACB', 'CACC', 'CBAA', 'CBAB', 'CBAC', 'CBBA', 'CBBB', 'CBBC', 'CBCA',
 'CBCB', 'CBCC', 'CCAA', 'CCAB', 'CCAC', 'CCBA', 'CCBB', 'CCBC', 'CCCA', 'CCCB',
 'CCCC']
>>> 


16. 映射器 starmap

>>> import itertools as it
>>> list(it.starmap(str.isupper, 'AbCDefgH'))
[True, False, True, True, False, False, False, True]
>>> list(it.starmap(lambda a,b,c:a+b+c,([1,2,3],[4,5,6],[7,8,9])))
[6, 15, 24]
>>> list(it.starmap(lambda *a:sum(a),[range(5),range(10),range(101)]))
[10, 45, 5050]
>>> 



17. 元组器 tee

返回多个迭代器的元组

>>> import itertools as it
>>> [list(i) for i in it.tee([1,2,3],3)]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
>>> it.tee([1,2,3],3)
(<itertools._tee object at 0x030711A8>,
 <itertools._tee object at 0x03078228>,
 <itertools._tee object at 0x0131FFE8>)
>>> 



18. 打包器 zip_longest

与内置函数zip()类似,但元素个数以最长的迭代器为准

>>> import itertools as it
>>> list(it.zip_longest('ABCDE',range(1,4)))
[('A', 1), ('B', 2), ('C', 3), ('D', None), ('E', None)]
>>> list(zip('ABCDE',range(1,4)))
[('A', 1), ('B', 2), ('C', 3)]
>>> list(it.zip_longest('ABCDE',range(1,4),[1,2,3,4]))
[('A', 1, 1), ('B', 2, 2), ('C', 3, 3), ('D', None, 4), ('E', None, None)]
>>> 

名字我随便起的,形像就好。看下来如何?十八兵器,样样精通了吗?其实掌握个几样“称手的”即可,何必面面俱到呢 ^_^

目录
相关文章
|
12天前
|
调度 开发者 Python
Python中的异步编程:理解asyncio库
在Python的世界里,异步编程是一种高效处理I/O密集型任务的方法。本文将深入探讨Python的asyncio库,它是实现异步编程的核心。我们将从asyncio的基本概念出发,逐步解析事件循环、协程、任务和期货的概念,并通过实例展示如何使用asyncio来编写异步代码。不同于传统的同步编程,异步编程能够让程序在等待I/O操作完成时释放资源去处理其他任务,从而提高程序的整体效率和响应速度。
|
15天前
|
数据采集 存储 数据挖掘
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第27天】在数据分析领域,Python的Pandas库因其强大的数据处理能力而备受青睐。本文介绍了Pandas在数据导入、清洗、转换、聚合、时间序列分析和数据合并等方面的高效技巧,帮助数据分析师快速处理复杂数据集,提高工作效率。
44 0
|
8天前
|
数据库 Python
异步编程不再难!Python asyncio库实战,让你的代码流畅如丝!
在编程中,随着应用复杂度的提升,对并发和异步处理的需求日益增长。Python的asyncio库通过async和await关键字,简化了异步编程,使其变得流畅高效。本文将通过实战示例,介绍异步编程的基本概念、如何使用asyncio编写异步代码以及处理多个异步任务的方法,帮助你掌握异步编程技巧,提高代码性能。
26 4
|
8天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
19 2
|
14天前
|
数据采集 JSON 测试技术
Python爬虫神器requests库的使用
在现代编程中,网络请求是必不可少的部分。本文详细介绍 Python 的 requests 库,一个功能强大且易用的 HTTP 请求库。内容涵盖安装、基本功能(如发送 GET 和 POST 请求、设置请求头、处理响应)、高级功能(如会话管理和文件上传)以及实际应用场景。通过本文,你将全面掌握 requests 库的使用方法。🚀🌟
36 7
|
14天前
|
机器学习/深度学习 数据采集 算法
Python机器学习:Scikit-learn库的高效使用技巧
【10月更文挑战第28天】Scikit-learn 是 Python 中最受欢迎的机器学习库之一,以其简洁的 API、丰富的算法和良好的文档支持而受到开发者喜爱。本文介绍了 Scikit-learn 的高效使用技巧,包括数据预处理(如使用 Pipeline 和 ColumnTransformer)、模型选择与评估(如交叉验证和 GridSearchCV)以及模型持久化(如使用 joblib)。通过这些技巧,你可以在机器学习项目中事半功倍。
21 3
|
17天前
|
数据采集 数据可视化 数据处理
如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`)
本文介绍了如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`),加载历史数据,计算均线和其他技术指标,实现交易逻辑,记录和可视化交易结果。示例代码展示了如何根据均线交叉和价格条件进行开仓、止损和止盈操作。实际应用时需注意数据质量、交易成本和风险管理。
37 5
|
16天前
|
存储 数据挖掘 数据处理
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第26天】Python 是数据分析领域的热门语言,Pandas 库以其高效的数据处理功能成为数据科学家的利器。本文介绍 Pandas 在数据读取、筛选、分组、转换和合并等方面的高效技巧,并通过示例代码展示其实际应用。
30 2
|
7天前
|
数据采集 数据可视化 数据挖掘
利用Python进行数据分析:Pandas库实战指南
利用Python进行数据分析:Pandas库实战指南
|
14天前
|
文字识别 自然语言处理 API
Python中的文字识别利器:pytesseract库
`pytesseract` 是一个基于 Google Tesseract-OCR 引擎的 Python 库,能够从图像中提取文字,支持多种语言,易于使用且兼容性强。本文介绍了 `pytesseract` 的安装、基本功能、高级特性和实际应用场景,帮助读者快速掌握 OCR 技术。
30 0