【问题标题】:Obtaining recursively permutations of a single list获取单个列表的递归排列
【发布时间】:2021-12-31 00:29:28
【问题描述】:

我在 Python 中工作,我想获得单个列表的某种“排列”。我会尽力解释问题,但如果有任何疑问,请告诉我。

假设我们有一个字符串列表a = ['?','A','A','A'],即有三个'A' 元素:n=3。我想创建一种方法来获取'A's 的所有排列(其余元素为'?'),从某种意义上说,在每个“排列层”中,'A' 的数量是递减的s 减一:n=n-1。

通过示例,这可以更好地理解:

例如,对于a,我们将在第一个“置换层”(n=3-1) 中获得a0 = ['?','A','A','?']、a1 = ['?','A','?','A'] 和a2 = ['?','?','A','A']。同理,在第二个“置换层”(n=3-1-1);对于a0,我们将有a00 = ['?','A','?','?'] 和a01 = ['?','?','A','?'],对于a1,我们将有a10 = ['?','A','?','?'] 和a11 = ['?','?','?','A'],对于a2,我们将有a20 = ['?','?','A','?'] 和a21 = ['?','?','?','A']。我知道其中一些可能是多余的,例如a00 和a10;没有问题。

请注意,一旦达到n=1,就没有更多的排列层,因为每个结果都是aN = ['?','?','?','?']。

澄清:图层确实很重要,因为我想测试列表是否包含属性(不重要提及)以更深入地了解图层。我会更好地解释:如果 a0 拥有该属性,那么我们将探索 a00 和 a01,否则我们不会。这样,我们可能不会探索所有的排列。因此,我只需要给定列表的方法,该方法获得立即 NEXT 层的排列,而不是其余的排列。如果是n=1,则返回任何内容,例如foo。

我不知道如何找到这个或类似的问题(事实上,谈论排列是否正确?)。这里最接近的帖子似乎是Recursive list of permutations,其中提到了“笛卡尔积”和“重复组合”等术语。但问题不一样。

我不在乎使用哪种方法来达到解决方案,我不是在寻找效率;但是,我觉得这可以通过在 n 上进行递归以优雅的方式完成。

谁能解决我的问题?我希望代码是用 Python 或类似语言给出的。

编辑 1

使用itertools.permutations() 不会产生预期的结果:

import itertools
a = ['?', 'A', 'A', 'A']

b = itertools.permutations(a)
for j in list(b): 
    print(j) 

打印出来:

('?', 'A', 'A', 'A')
('?', 'A', 'A', 'A')
('?', 'A', 'A', 'A')
('?', 'A', 'A', 'A')
('?', 'A', 'A', 'A')
('?', 'A', 'A', 'A')
('A', '?', 'A', 'A')
('A', '?', 'A', 'A')
('A', 'A', '?', 'A')
('A', 'A', 'A', '?')
('A', 'A', '?', 'A')
('A', 'A', 'A', '?')
('A', '?', 'A', 'A')
('A', '?', 'A', 'A')
('A', 'A', '?', 'A')
('A', 'A', 'A', '?')
('A', 'A', '?', 'A')
('A', 'A', 'A', '?')
('A', '?', 'A', 'A')
('A', '?', 'A', 'A')
('A', 'A', '?', 'A')
('A', 'A', 'A', '?')
('A', 'A', '?', 'A')
('A', 'A', 'A', '?')

请注意,其中没有一个预期结果,因为As 的数量并未减少。

【问题讨论】:

  • 层重要吗,还是您只想要所有排列(可能带有冗余)?
  • 你能用itertools.permutations()吗?
  • 您好,@ScottHunter,感谢您的提问!该层确实很重要,因为我想测试一个列表是否包含一个属性(不重要提及)以更深入地了解该层。我会更好地解释:如果a0 拥有该属性,那么我们将探索a00 和a01,否则我们不会。这样,我们可能不会探索所有的排列。
  • 嗨,@Barmar 我,感谢您的回答!不知道,马上试试!
  • 因此,我只需要在给定列表的情况下获取立即 NEXT 层的排列的方法,而不是其余的。如果是n=1,则返回任何内容,例如foo。

标签: python list subset permutation combinatorics


【解决方案1】:

听起来你想要一种方法来列出用?s 替换As 的某个子集的所有方法,这意味着它与找到所有选择一个子集的方法相同As(itertools 有代码)。

【讨论】:

  • 你好!如果代码是 permutations(正如另一条评论中所建议的那样),这不会产生预期的结果:请参阅帖子中的 EDIT 1。
【解决方案2】:

那些并不是真正的排列。它们是 4 个 ['A','?'] 列表的乘积。

您可以使用 itertool 的 product 函数在不递归的情况下获得它们:

from itertools import product

for p in product(*['A?']*4): print(p)
('A', 'A', 'A', 'A')
('A', 'A', 'A', '?')
('A', 'A', '?', 'A')
('A', 'A', '?', '?')
('A', '?', 'A', 'A')
('A', '?', 'A', '?')
('A', '?', '?', 'A')
('A', '?', '?', '?')
('?', 'A', 'A', 'A')
('?', 'A', 'A', '?')
('?', 'A', '?', 'A')
('?', 'A', '?', '?')
('?', '?', 'A', 'A')
('?', '?', 'A', '?')
('?', '?', '?', 'A')
('?', '?', '?', '?')

对于递归版本,您可以将每个值(A 或 ?)向下传递,以 n-1 作为计数:

def prod(values,n,result=[]):
    for v in values:
        if n == 1: yield [*result,v]
        else: yield from prod(values,n-1,[*result,v])

【讨论】:

  • 我已经能够通过修改此代码来解决问题!非常感谢!我应该在另一个编辑中发布它吗?
  • 是的,请发布您的最终解决方案。它可能会对将来发现此问题的人有所帮助。
猜你喜欢
  • 1970-01-01
  • 2011-11-26
  • 2018-10-07
  • 2021-09-15
  • 1970-01-01
  • 2011-06-18
  • 2011-07-23
  • 2012-11-17
  • 2013-07-23
相关资源
最近更新 更多