为什么Python的itertools.permutations包含重复项? (当原始列表重复时)

普遍认为,n个不同符号的列表有n! 排列。 但是,当符号不明确时,在math和其他地方最常见的惯例似乎是只计算不同的排列。 因此,列表[1, 1, 2] 1,1,2 [1, 1, 2]的排列通常被认为是

[1, 1, 2], [1, 2, 1], [2, 1, 1] 。 事实上,下面的C ++代码正好打印出这三个:

int a[] = {1, 1, 2}; do { cout<

另一方面,Python的itertools.permutations似乎打印别的东西:

import itertools for a in itertools.permutations([1, 1, 2]): print a

这打印

(1, 1, 2) (1, 2, 1) (1, 1, 2) (1, 2, 1) (2, 1, 1) (2, 1, 1)

正如用户Artsiom Rudzenka在答复中指出的那样, Python文档中这样说:

元素根据他们的位置被视为唯一的,而不是他们的价值。

我的问题:为什么这个devise决定了?

看来按照惯例,会给出更有用的结果(实际上它通常正是我想要的),还是有一些我缺less的Python行为的应用程序?

[或者是一些执行问题? 在next_permutation的algorithm – 例如在这里(由我)在这里解释StackOverflow ,并在这里显示为O(1)摊销 – 看起来是有效的,并且可以在Python中实现,但Python做的事情更有效,因为它不保证字典顺序基于价值? 如果是的话,效率提高是否值得呢?]

我不能代表itertools.permutations (Raymond Hettinger)的devise师,但在我看来,有一些赞成devise的观点:

首先,如果你使用next_permutation风格的方法,那么你只能传入支持线性sorting的对象。 而itertools.permutations提供了任何types的对象的排列。 想象一下,这将是多么令人讨厌:

>>> list(itertools.permutations([1+2j, 1-2j, 2+j, 2-j])) Traceback (most recent call last): File "", line 1, in TypeError: no ordering relation is defined for complex numbers

其次,通过不testing对象上的相等性, itertools.permutations避免了在通常情况下不需要调用__eq__方法的代价。

基本上, itertools.permutations可靠而廉价地解决了常见的情况。 当然有一个论点需要提出, itertools应该提供一个避免重复排列的函数,但是除了itertools.permutations之外,这个函数应该不是itertools.permutations而是它。 为什么不写这样的function并提交补丁?

我接受Gareth Rees的答案作为最吸引人的解释(Python库devise者的答案不足),即Python的itertools.permutations没有比较元素的值。 想一想,这就是问题所在,但是我现在看到它是如何被看作是一个优势,取决于通常使用itertools.permutations 。

为了完整起见,我比较了三种产生所有不同排列的方法。 方法1是非常低效的记忆方式和时间方式,但要求最less的新代码,就是包装Python的itertools.permutations ,就像zeekay的答案一样。 方法2是C ++的next_permutation一个基于生成器的版本,来自这个博客文章 。 方法3是我写的更接近于C ++的next_permutationalgorithm ; 它就地修改了这个列表(我没有把它做得太笼统)。

def next_permutationS(l): n = len(l) #Step 1: Find tail last = n-1 #tail is from `last` to end while last>0: if l[last-1] < l[last]: break last -= 1 #Step 2: Increase the number just before tail if last>0: small = l[last-1] big = n-1 while l[big] <= small: big -= 1 l[last-1], l[big] = l[big], small #Step 3: Reverse tail i = last j = n-1 while i < j: l[i], l[j] = l[j], l[i] i += 1 j -= 1 return last>0

这里有一些结果。 我现在对Python的内置函数更加尊重:当元素全部(或者几乎全部)不同时,它比其他方法快三到四倍。 当然,当有很多重复的元素时,使用它是一个可怕的想法。

Some results ("us" means microseconds): l m_itertoolsp m_nextperm_b m_nextperm_s [1, 1, 2] 5.98 us 12.3 us 7.54 us [1, 2, 3, 4, 5, 6] 0.63 ms 2.69 ms 1.77 ms [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 6.93 s 13.68 s 8.75 s [1, 2, 3, 4, 6, 6, 6] 3.12 ms 3.34 ms 2.19 ms [1, 2, 2, 2, 2, 3, 3, 3, 3, 3] 2400 ms 5.87 ms 3.63 ms [1, 1, 1, 1, 1, 1, 1, 1, 1, 2] 2320000 us 89.9 us 51.5 us [1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4] 429000 ms 361 ms 228 ms

代码在这里,如果有人想探索。

通过包装itertools.permutations来获得您喜欢的行为是相当容易的,这可能会影响决策。 如文档中所述, itertools被devise为构build您自己的迭代器的构build块/工具的集合。

def unique(iterable): seen = set() for x in iterable: if x in seen: continue seen.add(x) yield x for a in unique(permutations([1, 1, 2])): print a (1, 1, 2) (1, 2, 1) (2, 1, 1)

但是,正如评论中指出的那样,这可能不是你想要的效率:

>>> %timeit iterate(permutations([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2])) 1 loops, best of 3: 4.27 s per loop >>> %timeit iterate(unique(permutations([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]))) 1 loops, best of 3: 13.2 s per loop

也许如果有足够的兴趣, itertools.permutations的新function或可选参数可以被添加到itertools ,以更有效地产生排列而不重复。

我也觉得itertools没有更直观的独特排列概念的function。 生成重复排列只是为了select其中的唯一对于任何严重的应用程序来说都是不可能的。

我写了自己的迭代生成器函数,其行为与itertools.permutations类似,但不返回重复。 只考虑原始列表的排列,可以使用标准的itertools库创build子列表。

def unique_permutations(t): lt = list(t) lnt = len(lt) if lnt == 1: yield lt st = set(t) for d in st: lt.remove(d) for perm in unique_permutations(lt): yield [d]+perm lt.append(d)

也许我错了,但似乎这样做的理由是: “元素根据他们的位置被视为唯一的,而不是他们的价值。 所以如果input元素是唯一的,那么在每个排列中都不会有重复的值。 你已经指定了(1,1,2),从你的angular度来看1在0索引和1在1索引是一样的 – 但是这并不是如此,因为排列python实现使用索引而不是值。

所以如果我们看一下默认的python permutations实现,我们会看到它使用索引:

def permutations(iterable, r=None): pool = tuple(iterable) n = len(pool) r = n if r is None else r for indices in product(range(n), repeat=r): if len(set(indices)) == r: yield tuple(pool[i] for i in indices)

例如,如果将input更改为[1,2,3],则将得到正确的排列([(1,2,3),(1,3,2),(2,1,3),(2,3 ,1),(3,1,2),(3,2,1)]),因为这些值是唯一的。

permutations python_为什么Python的itertools.permutations包含重复项? (当原始列表重复时)...相关推荐

  1. insert 语句的选择列表包含的项多于插入列表中的项_如何定义和使用Python列表(Lists)

    Python中最简单的数据集合是一个列表(list).列表是方括号内用逗号分隔的任何数据项列表.通常,就像使用变量一样,使用=符号为Python列表分配名称. 如果列表中包含数字,则不要在其周围使用引 ...

  2. python集合如何去除重复数据_Python 迭代删除重复项,集合删除重复项

    1. 迭代删除重复项:先排序列表项,然后通过新迭代(not in)去除重复项,分片打印 def sanitize(time_string): if '-' in time_string: splitt ...

  3. python查找列表重复项_python – 在列表中查找项目和重复项

    我正在使用 Python并考虑以下问题:给出一个列表,例如[1,0,-2,0,0,4,5,0,3]多次包含0的整数,我希望有这些0和每一个的索引是它出现在列表中的次数,直到出现不同的元素或列表结束. ...

  4. python输出字典的前十项,从字典列表中获取前5个值?

    我从api密钥获取json. 这是我的json:{'[{"count":27,"stem":"obama","term" ...

  5. python列表删除重复项_五分钟学会三种Excel重复项删除方法,工作效率大杀器!...

    点击蓝字 关注我们 在统计数据过程中, 同一份数据可能由于渠道的不同而进行了多次统计, 在输入数据时, 可能因为操作失误重复输入数据.种种原因造成数据表中的数据存在重复现象, 删除重复数据是数据清洗的 ...

  6. 6种在 Python 中从 List 中删除重复项的方法

    来源 | https://medium.com/@cookbug/six-ways-to-remove-duplicates-from-list-in-python-970d998b1384 翻译 | ...

  7. python itertools combination_Python itertools.combinations 和 itertools.permutations 等价代码实现...

    最近编程时经常要用到排序组合的代码,想当年还抱着一些情况买了一本<组合数学>,不过现在这货也不知道被自己放哪里了,估计不会是垫桌子腿了吧. 由于去年去东北大学考博面试的时候遇到过可能涉及排 ...

  8. 【python日用】itertools.permutations用法

    标准语法 itertools.permutations(iterable[, r]) 含义 Return successive r length permutations of elements in ...

  9. itertools.permutations()结构及上下文||排列

    itertools 官方文档 itertools是2.3版本加入的用于创建循环用迭代器的函数模块. itertools 模块提供的迭代器函数有以下几种类型: 无限迭代器:生成一个无限序列,比如自然数序 ...

最新文章

  1. 实现等待窗体的几种方式
  2. 附录6:TensorFlow基础(二)
  3. iBatis报java.lang.RuntimeException: Error setting property错误
  4. 如何使用SAP C4C Repository Explorer里的BO test shell
  5. 进阶篇-安卓系统:2.多点触控的交互处理
  6. [Java基础]Date类基础
  7. 图像处理之三---摄像头灰度值处理
  8. nginx https 配置
  9. pythondraw解释_科学网—Draw figures with Python - 高琳琳的博文
  10. linux系统声卡安装教程,关于Linux系统声卡驱动的安装与配置
  11. 常见的弱口令字典1000~一石三鸟
  12. 智能对话机器人之多轮对话工作机制 | Chatopera
  13. 应用程序正常初始化(0xc000007b)失败,请单击“确定”,终止应用程序的问题处理
  14. HDU4043 FXTZ
  15. vue导出excel (兼容ie)
  16. 计算机夏令营英语自我介绍,夏令营英文自我介绍范文5篇
  17. 互联网电商模式的迅速发展,消费返利模式你知道吗?
  18. 微信H5页面背景音乐自动播放
  19. 【学习笔记】Matlab自编图像卷积函数
  20. Overleaf论文撰写英语科技论文参考

热门文章

  1. ASP.NET Core MVC – 自定义 Tag Helpers
  2. Visual Studio 2017 15.3 预览版发布,接近最终版
  3. DDD理论学习系列(11)-- 工厂
  4. WebAssembly,开发者赢了
  5. 老司机实战Windows Server Docker:5 Windows Server Dockerfile葵花宝典
  6. 为什么微软逐步转变为开源公司
  7. 02.CSS基础笔记及导入
  8. WIN10 查看已经连接的wifi的密码
  9. [转]IPython介绍
  10. vuejs 和 element 搭建的一个后台管理界面【收藏】