资讯专栏INFORMATION COLUMN

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

番茄西红柿 / 2895人阅读

摘要:三国时代著名的兵器鉴别家吕虔根据兵器的特点对汉武帝钦定的十八般兵器重新排列为九长九短。明代五杂俎和清代坚集两书所载十八般兵器为弓弩枪刀剑矛盾斧钺戟黄锏挝殳棍叉耙头锦绳套索白打拳术。后人称其为小十八般。

知识点

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

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

汉武于元封四年(公元前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(11))>>> list(it.accumulate(range(11)))[0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55]>>> 

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

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

2. 连接器 chain

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

>>> import itertools as it>>> it.chain(range(3),[3,4,5],{6,7},(i for i in range(8,11)))>>> 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

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

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

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>> 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)]

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)(, , )>>> 

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)]>>> 

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119018.html

相关文章

  • [这段代码很Pythonic]相见恨晚itertools

    摘要:使用中的函数大多是返回各种迭代器对象,其中很多函数的作用我们平时要写很多代码才能达到,而在运行效率上反而更低,毕竟人家是系统库。连接多个列表或者迭代器。 前言 最近事情不是很多,想写一些技术文章分享给大家,同时也对自己一段时间来碎片化接受的知识进行一下梳理,所谓写清楚才能说清楚,说清楚才能想清楚,就是这个道理了。 很多人都致力于把Python代码写得更Pythonic,一来更符合规范且...

    leap_frog 评论0 收藏0
  • 0x05 Python数据分析,Anaconda八斩刀

    摘要:做数据分析,,你值得拥有。的包管理器有和,本来是很方便的。另外,本身还提供了包管理器来安装或升级相应的包。八斩刀是咏春中最厉害的兵器,是一条大蟒蛇,翻译为水蟒。如果数据科学是武侠中的咏春,那么便是数据科学中的八斩刀。 摘要:武侠,是成人的童话。江湖,是门派的斗争。数据科学已经开山立派,Python便是其中独领风搔的兵器。如果数据科学是IT武侠中的咏春,那么Anaconda便是数据科学中...

    yimo 评论0 收藏0
  • 软件测试江湖之公会武器之争

    摘要:为了保证各自的核心利益,避免盲目恶性竞争,最终三大公会达成了一个共识将软件测试江湖里的神兵利器分为四大类功能自动化测试武器性能测试武器测试管理武器单元测试武器。 有人的地方就有江湖,有江湖的地方就有恩怨。 软件测试也有自己的江湖,也有自己的纷争。 软件测试江湖一直存在于武林中,只是对外行事低调,从不惹是非,是以未受到武林中各路人士的关注,直到近年来互联网这股势力的崛起将软件测试这一传统...

    Berwin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<