防止重复来自 itertools.permutations

raw*_*ang 7 python

我想使用 2 A 和 2 B 获得 4 个字符串的所有唯一排列

from itertools import permutations

perm = permutations('AABB', 4)
for i in list(perm):
    print(i)
Run Code Online (Sandbox Code Playgroud)

这让我

('A', 'A', 'B', 'B')
('A', 'A', 'B', 'B')
('A', 'B', 'A', 'B')
('A', 'B', 'B', 'A')
...
Run Code Online (Sandbox Code Playgroud)

如您所见,我得到了重复项。我想这是因为它把第一名和第二名的 A 视为不同的值,但对我来说 AABB 只是 1 个独特的结果。

我可以通过将它们全部放入一个集合中以消除重复来解决此结果,但我认为我只是错误地使用了置换函数。

如何使用置换函数通过使用 2 个 A 和 2 个 B 来获得所有唯一的置换而不会得到重复?

小智 9

您应该使用more_itertools.distinct_permutations它来实现这一目标。

from more_itertools import distinct_permutations as idp
for p in idp('ABB'):
    print(p)
Run Code Online (Sandbox Code Playgroud)

  • [文档](https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_permutations)指出这“相当于set(permutations(iterable)),除了不生成重复项并且扔掉。对于更大的输入序列,这要高效得多。” (2认同)

Ror*_*ton 7

在 itertools 中没有直接的方法可以做到这一点。permutations()状态的文档:

元素被视为唯一基于它们的位置,而不是它们的值。

这意味着尽管这两个As 看起来与您相同,但 itertools 将它们视为不相等,因为它们在原始字符串中的位置不同。

您想要的结果数称为 4 个值的多项式系数,其中 2 个相等,另外 2 个相等。您可以通过编码自己的等效函数来获得所需的内容,permutations但这需要一段时间来编码和调试。(multinomial虽然这个词指的是一个数字,而不是实际的列表,但也可以称之为它。)一种更简单的方法,可能在执行和内存使用方面较慢,但在编程中要快得多,是使用permutationsPythonset删除重复项。你可以这样做:

from itertools import permutations

perm = permutations('AABB', 4)
for i in set(perm):
    print(i)
Run Code Online (Sandbox Code Playgroud)

这可能会导致打印输出的顺序不同。如果要恢复原始顺序,请使用sorted(set(perm)), 因为permutations按字典顺序返回(如果原始字符串按排序顺序)。