泻药。

大略看了一眼。

第一个元素有 n 种可能,第二个元素有 n-1 种可能,以此类推。

而观察可知 cycles 就是个 (n, n-1, n-2, ..., n-r+1) 进制的变进制数,因此 cycles 就是个计数器,直接对应到 “正在枚举输出的元素是哪个”。只不过这个变进制数的倒序对应了permutation的正序。

再注意到它给出的样例顺序非常朴素,永远是下标小的元素优先枚举,不是什么精妙的枚举顺序。带着这个信息我们再看 indices,很容易明白:cycles 为 (n, n-1, n-2..) 时,indices 为 (0, 1, 2, ..., n-1);

cycles 为 (n-1, n-1, n-2, ...) 时, indices 为 (1, 0, 2, ..., n-1); // 交换了下标为 i=0 和 j=-(n-1) 的两个元素

cycles 为 (n-2, n-1, n-2, ...) 时, indices 为 (2, 0, 1, ..., n-1); // 交换了下标为 i=0 和 j=-(n-2) 的两个元素

等等

因此 indices 就是记录一下朴素枚举顺序下的“当前排列”。

最后,注意你看的这份代码并非 python 标准库代码,而是一份为了方便理解而简化的代码。因为它说了:

Roughly equivalent to

至于这么一份为了简化的代码为什么非要用倒序枚举去做一个正序的事情,然后还时不时用 -j 去从右往左找元素(但是序列长度已知,所以从左往右找元素并不麻烦……),我觉得挺奇怪的。

EDIT: 再解释一句吧,那个代码可以看成下列递归程序的强行非递归版(省去了一些 boilerplate),注意我的版本里几乎每句话都来自原始代码,只是拆成了递归。

(cycles 哪里去了?cycles 就是栈上所有的 j)

def _perm(indices, i, n, r):

if i == r:

yield indices[:r]

else:

for j in range(n-i, 0, -1):

indices[i], indices[-j] = indices[-j], indices[i]

for result in _perm(indices, i+1, n, r):

yield result

indices[i:] = indices[i+1:] + indices[i:i+1]

def permutations(n, r):

indices = list(range(n))

return _perm(indices, 0, n, r)

python itertools.permutations_如何理解Python itertools.permutations中的全排列算法?相关推荐

  1. python装饰器作用-理解python中的装饰器

    一 什么是装饰器? 正如其名,装饰器的作用是为已经存在的对象增加额外功能(装饰),由此可使已有函数在无需代码改动的情况下增加额外功能:装饰器的本质是嵌套的函数且返回函数对象,即闭包.有关闭包的概念,可 ...

  2. python属性_深入理解python对象及属性

    类属性和实例属性 首先来看看类属性和类实例的属性在python中如何存储,通过__dir__方法来查看对象的属性 >>> class Test(object): pass >& ...

  3. 深入理解python特性_深入理解Python特性(7)

    克隆对象 Python中的赋值语句不会创建对象的副本,只是将名称绑定到对象上.对于不可变对象也是如此.但为了处理可变对象或可变对象集合,需要一种方法来创建这些对象的"真实副本"或& ...

  4. python的认识_理解 Python 中的 *args 和 **kwargs

    Python是支持可变参数的,最简单的方法莫过于使用默认参数,例如: def test_defargs(one, two = 2): print 'Required argument: ', one ...

  5. python画树叶-如何理解python一行代码实现一个爱心字符画?

    前言 python中有个很酷的效果,一行代码实现一个爱心字符,虽说是一行代码,但是理解起来还是比较难的,括号太多,并且使用了python的一些快捷小技巧.比如三元表达式,列表生成式,字符串拼接以及一个 ...

  6. python装饰器-如何理解Python装饰器?

    我从以下几点,由浅入深详细讲解一下Python装饰器:什么事装饰器? 为什么用装饰器? 在哪里用装饰器? 然后以示例+讲解相结合的方式阐述,同时会讲解一些在很多教程和书籍中不会涉及到的内容. 什么是P ...

  7. python多线程_干货|理解python多线程和多进程

    点击上方"AI遇见机器学习",选择"星标"公众号 原创干货,第一时间送达 一.多线程与多进程 在介绍Python多线程编程之前,先给大家复习一下进程和线程的概念 ...

  8. 让python飞:形象理解python 全局变量、局部变量、内部函数、外部函数、ascii码、内置函数

    Day06凯尔特与佛印闯双蛇洞 秦始皇得知有一兵马俑逃脱,立即派出大内高手凯尔特前去捉拿.凯尔特一路追踪到熊山寺,但寺门紧闭,遂从后门入寺. 凯尔特悄悄溜到后山,见到高台周围有许多狮子蠢蠢欲睡.高台上 ...

  9. python 多线程 setdaemon_彻底理解Python多线程中的setDaemon与join配有GIF示意

    在进行Python多线程编程时, join()和 setDaemon()是最常用的方法,下面说说两者的用法和区别. 1.join () 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B.jo ...

最新文章

  1. 利用vs.net快速开发windows服务(总结)
  2. 大数据时代下的迁移学习_继深度学习后,下一个热点技术是迁移学习
  3. GJM : Unity3D HIAR -【 快速入门 】 三、导入 SDK
  4. 【文文殿下】 [USACO08MAR]土地征用 题解
  5. 不抛出异常的swap
  6. GCC Command Options
  7. linux tomcat连接mysql步骤_Linux安装JDK 、TOMCAT 、MYSQL 步骤
  8. c语言参数列表定义一个三维数组,C语言多维数组
  9. c++堆内存默认大小_Java 自动内存管理
  10. 大数据培训(第一季) java基础-徐培成-专题视频课程
  11. 短视频如何选择背景音乐和配音?四个技巧来帮忙
  12. Clickhouse查询手册
  13. 2020强网杯部分题目复现
  14. 深圳租房信息聚类与回归分析
  15. 微软windows拼音繁体、简体中文切换
  16. 将字符串中的大写字母转化为小写字母
  17. 罗克韦尔 DeviceNet配置软件
  18. abaqus python_ABAQUS中的python语言入门
  19. [前端笔记——HTML介绍] 4.HTML文本基础+超链接+高级文本格式
  20. for in在python中什么意思_Python for i in range ()用法详解

热门文章

  1. dbeaver 设置编码_初学者必须知道的idea设置
  2. c语言 inline函数的总结,C++中inline函数详解
  3. [OpenGL ES 02]OpenGL ES渲染管线与着色器
  4. 在 Win vs2017 下编译 zint
  5. Segment Tree Beats 区间最值问题
  6. 怕死吗?研究人员推出可模拟“灵魂出窍”的VR系统
  7. 微信小程序 --- 获取网络状态
  8. Android TextView 带背景的文字垂直方向显示(ems属性)
  9. Web-HTML特殊符号的表示
  10. ISCW实验10:安装SDM到路由器的FLASH中