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初到大数据学习圈子的同学可能对爬虫都有 ...
随机推荐
- (android实战)破解apk
简单的总结几个关键步骤: 一.工具准备:apktool , dex2jar , jd-gui 二.使用dex2jar + jd-gui 得到apk的java源码 1.用解压工具从 apk包中取出 cl ...
- boost pool 和 object_pool
内存池(Memory Pool)是一种内存分配方式. 通常我们习惯直接使用new.malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的 ...
- SEO笔记:Anatomy of a URL
Dr. Peter J. Meyers 原文链接:https://moz.com/blog/seo-cheat-sheet-anatomy-of-a-url 原文主要通过对比讲解 SEO优化后的URL ...
- js中 a : function(){}这是什么格式? 代表什么含义?怎样学习这样的格式?
js中的json. 一种轻量级数据格式.json中的值是map形式的就是key->value. 具体看下边的示例; var person = { // 用 大括号括声明一个json. " ...
- hdu5880 Family View
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5880 题目: Family View Time Limit: 3000/1000 MS (Ja ...
- hdu1199 线段树
这题说的是给了 n 个操作. 每个操作会把 [a,b] 之间的球 涂为黑色或者 白色, 然后最后问 最长的连续的白色的 球有多少个,初始的时候全是黑的. 我们将所有的点离散化, 记得离散 a-1, b ...
- uva1401 dp+Trie
这题说的是给了一个长的字符串长度最大300000,又给了4000个单词 单词的长度不超过100.计算这个字符串能组成多少种不同单词的组合,求出方案总数.dp[i]以第i个字符为开始的字符串能有多少种的 ...
- 20155207 2016-2017-2 《Java程序设计》第八周学习总结
20155207 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 第15章 通用API 15.1 日志 15.1.1 日志API简介 java.util.lo ...
- 【运维技术】Jenkins配置使用教程
Jenkins配置使用教程 单机jenkins启动 软件安装和启动,必须含有java环境 # 安装jdk,参考其他教程,创建文件目录 mkdir -p /app/jenkins cd /app/jen ...
- Java的Servlet、Filter、Interceptor、Listener
写在前面: 使用Spring-Boot时,嵌入式Servlet容器可以通过扫描注解(@ServletComponentScan)的方式注册Servlet.Filter和Servlet规范的所有监听器( ...