我有一个反复的说法,
a = [0, 1, 2, 3]
我想要所有可能的基数3集合,例如:
第一个条件是具有替换属性的泛化,该属性允许任意元素重复任意次数。
我尝试过的事情:
itertools.permutation
不允许重复。
itertools.product(a, repeat=3)
允许元素重复两次并三次,这违反了第一个条件。
如果我将repeat = 2设置为长度2的子集,则需要3。
我该怎么做?
答案 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)}