如何使用itertools组合和排列找到它?

时间:2019-06-14 22:33:43

标签: python

我有一个反复的说法,

a = [0, 1, 2, 3]

我想要所有可能的基数3集合,例如:

  • 允许重复,直到重复不超过2个的约束为止。
  • 订单很重要。

第一个条件是具有替换属性的泛化,该属性允许任意元素重复任意次数。

我尝试过的事情:

itertools.permutation不允许重复。

itertools.product(a, repeat=3)允许元素重复两次并三次,这违反了第一个条件。 如果我将repeat = 2设置为长度2的子集,则需要3。

我该怎么做?

4 个答案:

答案 0 :(得分:2)

我认为itertools不会立即为您提供这种精细的控制。您将需要编写自己的算法或从itertools中获取一些输出并过滤所需的内容,例如:

from itertools import product
a = [0, 1, 2, 3]
cardinality = 4
repeats = 2
[c for c in product(a, repeat=cardinality) if len(set(c)) > cardinality - repeats]

输出

[(0, 0, 1, 2),
 (0, 0, 1, 3),
 (0, 0, 2, 1),
 (0, 0, 2, 3),
 (0, 0, 3, 1),
 (0, 0, 3, 2),
 (0, 1, 0, 2),
 (0, 1, 0, 3),
 (0, 1, 1, 2),
 (0, 1, 1, 3),
 (0, 1, 2, 0),
 (0, 1, 2, 1),
 (0, 1, 2, 2),
 (0, 1, 2, 3),
 (0, 1, 3, 0),
 (0, 1, 3, 1),

 ...

 (3, 2, 3, 1),
 (3, 3, 0, 1),
 (3, 3, 0, 2),
 (3, 3, 1, 0),
 (3, 3, 1, 2),
 (3, 3, 2, 0),
 (3, 3, 2, 1)]

答案 1 :(得分:2)

这里很脏。 (或者,不是我想的那么肮脏)在进行置换之前,请自己处理重复。采取一套措施以确保唯一性。

from itertools import permutations
n_repeats = 2
cardinality = 3
a = [0, 1, 2, 3]

for group in set(permutations(a*n_repeats, cardinality)):
    print(group)

输出代码段:

(3, 0, 2)
(0, 1, 1)
(1, 0, 3)
(1, 3, 2)
(3, 0, 3)
(0, 1, 2)
(1, 0, 0)
...

答案 2 :(得分:1)

您可以将product方法与索引一起使用,以便跟踪产品中重复索引的次数。如果大于2(允许最大重复),则忽略该乘积:

from itertools import product
from collections import Counter

max_repetitions = 2
a = [0, 1, 2, 3]

res = []
for p in product(enumerate(a), repeat=3):
    index_counts = Counter((i for i, _ in p))
    if not index_counts.most_common(1)[0][1] > max_repetitions:
        res.append([e for _, e in p])

print(res)

输出

[[0, 0, 1],
 [0, 0, 2],
 [0, 0, 3],
 [0, 1, 0],
 [0, 1, 1],
 [0, 1, 2],
 [0, 1, 3],
 [0, 2, 0],
 [0, 2, 1],
 [0, 2, 2],
 [0, 2, 3],
 [0, 3, 0],
 [0, 3, 1],
 [0, 3, 2],
 [0, 3, 3],
 [1, 0, 0],
 [1, 0, 1],
 [1, 0, 2],
 [1, 0, 3],
 [1, 1, 0],
 [1, 1, 2],
 [1, 1, 3],
 [1, 2, 0],
 [1, 2, 1],
 [1, 2, 2],
 [1, 2, 3],
 [1, 3, 0],
 [1, 3, 1],
 [1, 3, 2],
 [1, 3, 3],
 [2, 0, 0],
 [2, 0, 1],
 [2, 0, 2],
 [2, 0, 3],
 [2, 1, 0],
 [2, 1, 1],
 [2, 1, 2],
 [2, 1, 3],
 [2, 2, 0],
 [2, 2, 1],
 [2, 2, 3],
 [2, 3, 0],
 [2, 3, 1],
 [2, 3, 2],
 [2, 3, 3],
 [3, 0, 0],
 [3, 0, 1],
 [3, 0, 2],
 [3, 0, 3],
 [3, 1, 0],
 [3, 1, 1],
 [3, 1, 2],
 [3, 1, 3],
 [3, 2, 0],
 [3, 2, 1],
 [3, 2, 2],
 [3, 2, 3],
 [3, 3, 0],
 [3, 3, 1],
 [3, 3, 2]]

答案 3 :(得分:0)

如何使用集合difference或从itertools.product中减去:

cardinality = 3

set(itertools.product(a, repeat=cardinality )).difference(set((x,)*cardinality  for x in a))

set(itertools.product(a, repeat=cardinality )) - set((x,)*cardinality  for x in a)


Out[2024]:
{(0, 0, 1),
 (0, 0, 2),
 (0, 0, 3),
 (0, 1, 0),
 (0, 1, 1),
 (0, 1, 2),
 (0, 1, 3),
 (0, 2, 0),
 (0, 2, 1),
 (0, 2, 2),
 (0, 2, 3),
 (0, 3, 0),
 (0, 3, 1),
 (0, 3, 2),
 (0, 3, 3),
 (1, 0, 0),
 (1, 0, 1),
 (1, 0, 2),
 (1, 0, 3),
 (1, 1, 0),
 (1, 1, 2),
 (1, 1, 3),
 (1, 2, 0),
 (1, 2, 1),
 (1, 2, 2),
 (1, 2, 3),
 (1, 3, 0),
 (1, 3, 1),
 (1, 3, 2),
 (1, 3, 3),
 (2, 0, 0),
 (2, 0, 1),
 (2, 0, 2),
 (2, 0, 3),
 (2, 1, 0),
 (2, 1, 1),
 (2, 1, 2),
 (2, 1, 3),
 (2, 2, 0),
 (2, 2, 1),
 (2, 2, 3),
 (2, 3, 0),
 (2, 3, 1),
 (2, 3, 2),
 (2, 3, 3),
 (3, 0, 0),
 (3, 0, 1),
 (3, 0, 2),
 (3, 0, 3),
 (3, 1, 0),
 (3, 1, 1),
 (3, 1, 2),
 (3, 1, 3),
 (3, 2, 0),
 (3, 2, 1),
 (3, 2, 2),
 (3, 2, 3),
 (3, 3, 0),
 (3, 3, 1),
 (3, 3, 2)}