我必须列出有限重复的无序组合 即对于给定的唯一元素列表,例如card_set创建长度为combo_len的所有组合,其元素重复为max repeat_limit次
以下代码适用于combo_len = 3和repeat_limit = 2,其中card_set = range(5)
注意我需要无序组合。 即(0,0,1)和(0,1,0)是相同的,所以下面的解决方案链接不满足我的条件
This帖子告诉我如何获得有限重复的提示组合
import itertools
import pprint
card_set = list(range(5))
a = sorted(set(itertools.combinations_with_replacement(card_set,3)))
neg = [(i,i,i) for i in card_set]
b = set(a) - set(neg)
print('a###')
pprint.pprint(a)
print('b###')
pprint.pprint(b)
上面的代码给出了一个有限的2个重复的无序组合,即。 neg包含不需要的重复(0,0,0)(1,1,1)等
所以
b = set(a) - set(neg)
给我所需的一套
对于combo_len = 3和repeat_limit = 2,上述代码有效。如何为范围(13)combo_len = 7和repeat_limit = 4
创建代码输出:
a###
[(0, 0, 0),
(0, 0, 1),
(0, 0, 2),
(0, 0, 3),
(0, 0, 4),
(0, 1, 1),
(0, 1, 2),
(0, 1, 3),
(0, 1, 4),
(0, 2, 2),
(0, 2, 3),
(0, 2, 4),
(0, 3, 3),
(0, 3, 4),
(0, 4, 4),
(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 1, 4),
(1, 2, 2),
(1, 2, 3),
(1, 2, 4),
(1, 3, 3),
(1, 3, 4),
(1, 4, 4),
(2, 2, 2),
(2, 2, 3),
(2, 2, 4),
(2, 3, 3),
(2, 3, 4),
(2, 4, 4),
(3, 3, 3),
(3, 3, 4),
(3, 4, 4),
(4, 4, 4)]
b###
{(0, 0, 1),
(0, 0, 2),
(0, 0, 3),
(0, 0, 4),
(0, 1, 1),
(0, 1, 2),
(0, 1, 3),
(0, 1, 4),
(0, 2, 2),
(0, 2, 3),
(0, 2, 4),
(0, 3, 3),
(0, 3, 4),
(0, 4, 4),
(1, 1, 2),
(1, 1, 3),
(1, 1, 4),
(1, 2, 2),
(1, 2, 3),
(1, 2, 4),
(1, 3, 3),
(1, 3, 4),
(1, 4, 4),
(2, 2, 3),
(2, 2, 4),
(2, 3, 3),
(2, 3, 4),
(2, 4, 4),
(3, 3, 4),
(3, 4, 4)}
答案 0 :(得分:1)
您可以使用Counter
模块中的collections
类来查找给定元组中每个值的重复次数。对于每个元组,创建一个Counter
并检查重复的最大值。如果该最大值足够小,则接受元组;否则,拒绝它。
这是执行此操作的例程。如果我有更多的时间,我会很高兴。
小心这个例程。对于给定的range_size=13, combo_len=7, repeat_limit=4
值,结果是长度为49,205的列表。
from collections import Counter
from itertools import combinations_with_replacement
def unordered_combinations_with_limited_replacements(
range_size, combo_len, repeat_limit):
return [t for t in combinations_with_replacement(range(range_size), combo_len)
if max(Counter(t).values()) <= repeat_limit]
print(unordered_combinations_with_limited_replacements(5, 3, 2))
print(len(unordered_combinations_with_limited_replacements(13, 7, 4)))
这是打印输出:
[(0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 2), (0, 2, 3), (0, 2, 4), (0, 3, 3), (0, 3, 4), (0, 4, 4), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 3), (1, 3, 4), (1, 4, 4), (2, 2, 3), (2, 2, 4), (2, 3, 3), (2, 3, 4), (2, 4, 4), (3, 3, 4), (3, 4, 4)]
49205
答案 1 :(得分:0)
首先,示例代码中使用的neg
仅在repeat_limit等于combo_length时才有效。
所以我搜索了一些可以计算列表中不同元素的内容,并在Counter
模块中提出了collections
。下一步是使用简单的itertools.combinations_with_replacement
循环迭代for
创建的所有元素。如果Counter
对象中最常见的元素高于repeat_limit,请从列表中删除该元素。
此代码适用于每个范围,combo_length和repeat_limit:
import itertools
from collections import Counter
def getUnorderedCombo(list_range, combo_len, repeat_lim):
card_set = list(range(list_range))
a = list(set(itertools.combinations_with_replacement(card_set,combo_len)))
i = 0
while i < len(a):
c = Counter(a[i])
if c.most_common(1)[0][1] > repeat_lim:
del a[i]
i -= 1
i += 1
return set(a)