Python itertools.combinations 和 itertools.permutations 等价代码实现
最近编程时经常要用到排序组合的代码,想当年还抱着一些情况买了一本《组合数学》,不过现在这货也不知道被自己放哪里了,估计不会是垫桌子腿了吧。
由于去年去东北大学考博面试的时候遇到过可能涉及排列组合的编程题,要我当时很是十分的下不来台,所以现在遇到这货比较敏感,虽然用到的时候直接调用库就万事大吉,不过细细想来总觉不妥,遂把库函数的说明文档调了出来。
https://docs.python.org/dev/library/itertools.html#itertools.combinations
itertools.combinations(iterable, r)-
Return r length subsequences of elements from the input iterable.
Combinations are emitted in lexicographic sort order. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.
Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each combination.
Roughly equivalent to:
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(range(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = list(range(r))
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
初看这个代码感觉比较震惊,感觉这是什么鬼,代码量不是很大,不过实现的功能倒是要人感觉很强大。
以上代码虽然是等价代码,但是毕竟为源语言实现的,由此看看还是有些帮助的,估计真实库文件可能是使用C语言写的吧,这一点就不深入研究了。
pool = tuple(iterable) 该行代码则是将输入的可迭代对象转换为元组类型。
n = len(pool)
if r > n:
return
该段代码则是 得到元组长度n, 如果排序数 r 大于总长n, 则无意义,因此直接返回。
indices = list(range(r))
indices 为排序的索引, 也是每次迭代返回组合的索引号。
yield tuple(pool[i] for i in indices) 返回 默认的组合。如: pool 为(0,1,2,3,4), n=5, r=3, 默认的返回就是 (0,1,2) 。
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
判断返回的组合序号 是否为 终止的序号, 即(2,3,4)。
indices[i] += 1
返回的序号中如果那个位置的序号不等于终止序列中的对应该位置的序号则将该位置序号加一。
(0,1,2) =》 (0,1,3)
(0,1,3) =》 (0,1,4) (0,1,4) =》 (0,2, 4)
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
不同的序号位置加一后,其后续的位置依次在其前一位置上加一。即,(0,2,4)=》(0,2,3), (0,3,4)=》(1,3,4)=》(1,2,4)=》(1,2,3) https://docs.python.org/dev/library/itertools.html#itertools.permutations
itertools.permutations(iterable, r=None)-
Return successive r length permutations of elements in the iterable.
If r is not specified or is
None, then r defaults to the length of the iterable and all possible full-length permutations are generated.Permutations are emitted in lexicographic sort order. So, if the input iterable is sorted, the permutation tuples will be produced in sorted order.
Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each permutation.
Roughly equivalent to:
def permutations(iterable, r=None):
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = list(range(n))
cycles = list(range(n, n-r, -1))
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return
Python itertools.combinations 和 itertools.permutations 等价代码实现的更多相关文章
- 【Python】排列组合itertools & 集合set
■itertools 利用python的itertools可以轻松地进行排列组合运算 itertools的方法基本上都返回迭代器 比如 •itertools.combinations('abcd',2 ...
- python排列组合之itertools模块
1. 参考 几个有用的python函数 (笛卡尔积, 排列, 组合) 9.7. itertools — Functions creating iterators for efficient loopi ...
- 调用list(itertools.combinations(keys,3))出现MemoryError的解决办法
在python3.6中,如下例子: keys = list(newKeywords.keys()) resultkeys = list(itertools.combinations(keys,3)) ...
- [转] 三种Python下载url并保存文件的代码
原文 三种Python下载url并保存文件的代码 利用程序自己编写下载文件挺有意思的. Python中最流行的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib ...
- 使用python制作ArcGIS插件(2)代码编写
使用python制作ArcGIS插件(2)代码编写 by 李远祥 上一章节已经介绍了如何去搭建AddIn的界面,接下来要实现具体的功能,则到了具体的编程环节.由于使用的是python语言进行编程,则开 ...
- Python 爬虫的工具列表 附Github代码下载链接
Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...
- Python中生成器和迭代器的区别(代码在Python3.5下测试):
https://blog.csdn.net/u014745194/article/details/70176117 Python中生成器和迭代器的区别(代码在Python3.5下测试):Num01–& ...
- (转)Python新手写出漂亮的爬虫代码2——从json获取信息
https://blog.csdn.net/weixin_36604953/article/details/78592943 Python新手写出漂亮的爬虫代码2——从json获取信息好久没有写关于爬 ...
- (转)Python新手写出漂亮的爬虫代码1——从html获取信息
https://blog.csdn.net/weixin_36604953/article/details/78156605 Python新手写出漂亮的爬虫代码1初到大数据学习圈子的同学可能对爬虫都有 ...
随机推荐
- linux问题点滴,给普通用户添加sudo权限
最近又把linux捡起来了,虚拟机中安个元老级centos5.3继续搞.使用sudo临时获取超管权限命令时,提示”xxx is not in the sudoers file. This incide ...
- PAT 1082 Read Number in Chinese[难]
1082 Read Number in Chinese (25 分) Given an integer with no more than 9 digits, you are supposed to ...
- TeamViewer远程唤醒主机实战教程(多图)
前言:首先感谢大家来到这里.这篇文章其实算是一个教程,文章中涉及到了TeamViewer,Mac OS X,TP-Link家用路由器,以及花生壳DDNS,对于新手而言内容可能稍微有些多,但我相信按照我 ...
- python16_day27【crm 内嵌、删除、action】
一.内嵌 二.删除及关联关联显示 三.action
- acdream1174 合并同类项
这题说的是 给出N,a[1]... a[N],还有M,b[1]... b[M]long long ans = 0;for(int i = 1; i <= N; i ++) for(int ...
- 20155207 2016-2017-2 《Java程序设计》第八周学习总结
20155207 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 第15章 通用API 15.1 日志 15.1.1 日志API简介 java.util.lo ...
- python中小数点后取2位(四舍五入)以及取2位(四舍五不入)
一.小数点后取2位(四舍五入)的方法方法一:round()函数其实这个方法不推荐大家使用,查询资料发现里面的坑其实很多,python2和python3里面的坑还不太一样,在此简单描述一下python3 ...
- SoapUI、Jmeter、Postman三种接口测试工具的比较
1. 用例组织方式 首先是用例组织方式的不同,不同的目录结构与组织方式代表不同工具的测试思想,学习一个测试工具应该首先了解其组织方式. SoapUI的组织方式如下图,最上层是WorkSpace,每个 ...
- bzoj3629 / P4397 [JLOI2014]聪明的燕姿
P4397 [JLOI2014]聪明的燕姿 根据唯一分解定理 $n=q_{1}^{p_{1}}*q_{2}^{p_{2}}*q_{3}^{p_{3}}*......*q_{m}^{p_{m}}$ 而$ ...
- 2018-2019-1 20189215 《Linux内核原理与分析》第八周作业
可执行程序工作原理 <庖丁解牛>第七章书本知识总结 "目标文件"是指编译器生成的文件,"目标"指的是目标平台,例如x86或x64,它决定了编译器使用 ...