最近编程时经常要用到排序组合的代码,想当年还抱着一些情况买了一本《组合数学》,不过现在这货也不知道被自己放哪里了,估计不会是垫桌子腿了吧。

由于去年去东北大学考博面试的时候遇到过可能涉及排列组合的编程题,要我当时很是十分的下不来台,所以现在遇到这货比较敏感,虽然用到的时候直接调用库就万事大吉,不过细细想来总觉不妥,遂把库函数的说明文档调了出来。

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:

  1. def combinations(iterable, r):
  2. # combinations('ABCD', 2) --> AB AC AD BC BD CD
  3. # combinations(range(4), 3) --> 012 013 023 123
  4. pool = tuple(iterable)
  5. n = len(pool)
  6. if r > n:
  7. return
  8. indices = list(range(r))
  9. yield tuple(pool[i] for i in indices)
  10. while True:
  11. for i in reversed(range(r)):
  12. if indices[i] != i + n - r:
  13. break
  14. else:
  15. return
  16. indices[i] += 1
  17. for j in range(i+1, r):
  18. indices[j] = indices[j-1] + 1
  19. yield tuple(pool[i] for i in indices)

初看这个代码感觉比较震惊,感觉这是什么鬼,代码量不是很大,不过实现的功能倒是要人感觉很强大。

以上代码虽然是等价代码,但是毕竟为源语言实现的,由此看看还是有些帮助的,估计真实库文件可能是使用C语言写的吧,这一点就不深入研究了。

  1. pool = tuple(iterable) 该行代码则是将输入的可迭代对象转换为元组类型。
  2.  
  1. n = len(pool)
  2. if r > n:
  3. return

该段代码则是 得到元组长度n,  如果排序数 r 大于总长n, 则无意义,因此直接返回。

  1. indices = list(range(r))
    indices 为排序的索引, 也是每次迭代返回组合的索引号。
  2.  
  1. yield tuple(pool[i] for i in indices)
  2.  
  3. 返回 默认的组合。如: pool 为(0,1,2,3,4), n=5, r=3, 默认的返回就是 0,1,2
  1. for i in reversed(range(r)):
  2. if indices[i] != i + n - r:
  3. break
  1. 判断返回的组合序号 是否为 终止的序号, 即(2,3,4)。
  2.  
  1. indices[i] += 1
    返回的序号中如果那个位置的序号不等于终止序列中的对应该位置的序号则将该位置序号加一。
    0,1,2 =》 0,1,3
    0,1,3 =》 0,1,4
  2.  
  3. 0,1,4 =》 02, 4
  1.  
  1. for j in range(i+1, r):
  2. indices[j] = indices[j-1] + 1
  1. 不同的序号位置加一后,其后续的位置依次在其前一位置上加一。即,(0,2,4)=》(0,2,3), 0,3,4)=》(1,3,4)=》(1,2,4)=》(1,23
  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:

  1.  
  1. def permutations(iterable, r=None):
  2. # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
  3. # permutations(range(3)) --> 012 021 102 120 201 210
  4. pool = tuple(iterable)
  5. n = len(pool)
  6. r = n if r is None else r
  7. if r > n:
  8. return
  9. indices = list(range(n))
  10. cycles = list(range(n, n-r, -1))
  11. yield tuple(pool[i] for i in indices[:r])
  12. while n:
  13. for i in reversed(range(r)):
  14. cycles[i] -= 1
  15. if cycles[i] == 0:
  16. indices[i:] = indices[i+1:] + indices[i:i+1]
  17. cycles[i] = n - i
  18. else:
  19. j = cycles[i]
  20. indices[i], indices[-j] = indices[-j], indices[i]
  21. yield tuple(pool[i] for i in indices[:r])
  22. break
  23. else:
  24. return
  1.  

Python itertools.combinations 和 itertools.permutations 等价代码实现的更多相关文章

  1. 【Python】排列组合itertools & 集合set

    ■itertools 利用python的itertools可以轻松地进行排列组合运算 itertools的方法基本上都返回迭代器 比如 •itertools.combinations('abcd',2 ...

  2. python排列组合之itertools模块

    1. 参考 几个有用的python函数 (笛卡尔积, 排列, 组合) 9.7. itertools — Functions creating iterators for efficient loopi ...

  3. 调用list(itertools.combinations(keys,3))出现MemoryError的解决办法

    在python3.6中,如下例子: keys = list(newKeywords.keys()) resultkeys = list(itertools.combinations(keys,3)) ...

  4. [转] 三种Python下载url并保存文件的代码

    原文 三种Python下载url并保存文件的代码 利用程序自己编写下载文件挺有意思的. Python中最流行的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib ...

  5. 使用python制作ArcGIS插件(2)代码编写

    使用python制作ArcGIS插件(2)代码编写 by 李远祥 上一章节已经介绍了如何去搭建AddIn的界面,接下来要实现具体的功能,则到了具体的编程环节.由于使用的是python语言进行编程,则开 ...

  6. Python 爬虫的工具列表 附Github代码下载链接

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  7. Python中生成器和迭代器的区别(代码在Python3.5下测试):

    https://blog.csdn.net/u014745194/article/details/70176117 Python中生成器和迭代器的区别(代码在Python3.5下测试):Num01–& ...

  8. (转)Python新手写出漂亮的爬虫代码2——从json获取信息

    https://blog.csdn.net/weixin_36604953/article/details/78592943 Python新手写出漂亮的爬虫代码2——从json获取信息好久没有写关于爬 ...

  9. (转)Python新手写出漂亮的爬虫代码1——从html获取信息

    https://blog.csdn.net/weixin_36604953/article/details/78156605 Python新手写出漂亮的爬虫代码1初到大数据学习圈子的同学可能对爬虫都有 ...

随机推荐

  1. NodeJS学习笔记五

    Promise简介 所谓Promise,就是一个对象,用来传递异步操作的消息. Promise对象有以下两个特点. (1)对象的状态不受外界影响.Promise对象代表一个异步操作,有三种状态:Pen ...

  2. (1)了解cocostudio基础

    操作界面   Cocos Studio的界面主要分为菜单栏.工具栏.对象面板.资源面板.画布面板.属性面板.动画面板.输出窗口.状态栏九部分组成,如下图: 菜单栏   菜单栏为Cocos Studio ...

  3. linux centos7 erlang rabbitmq安装

    最终的安装目录为/opt/erlang 和 /opt/rabbitmq wget http://erlang.org/download/otp_src_21.0.tar.gztar zxvf otp_ ...

  4. 已有模板与tp框架的结合 (前台)

    已有模板与tp框架的结合 具体步骤   A.复制模板文件到view指定目录 B. 复合css .js.img.静态资源文件到系统指定目录 C. 把静态资源(css,js,img)文件的路径设置为“常量 ...

  5. springcloud10---feign-with-hystrix_factory

    package com.itmuch.cloud; import org.springframework.boot.SpringApplication; import org.springframew ...

  6. jmeter导入csv压测

    压测csv数据源(设置为utf-8格式),jmeter不需要第一行参数名 新建一个线程组,根据压测数据调整设置需要的循环次数(测试数据有9行,设置循环次数为9) 添加http头信息 Content-T ...

  7. 使用cronolog工具给tomcat进行日志切割

    关于cronolog的用法查看:https://www.freebsd.org/cgi/man.cgi?query=cronolog&apropos=0&sektion=0&m ...

  8. 如何把js的循环写成异步的

    针对这里的问题:深入理解node.js异步编程:基础篇https://cnodejs.org/topic/533d6edbc2621e680800e0ea 这一节有一个代码:###4.1 Node.j ...

  9. Matlab绘图基础——利用axes(坐标系图形对象)绘制重叠图像 及 一图多轴(一幅图绘制多个坐标轴)

    描述 axes在当前窗口中创建一个包含默认属性坐标系 axes('PropertyName',propertyvalue,...)创建坐标系时,同时指定它的一些属性,没有指定的使用DefaultAxe ...

  10. [bug report] 当springboot报错 找不到类 javax.xml.bind.JAXBException

    <!--以下四个依赖均是javax.xml.bind.JAXBException的依赖 在java6/7/8默认支持,java9不再支持--> <dependency> < ...