[英]All posible combinations of numbers on a list
I need to find all the possible combinations of a list with a defined length and numbers of defined size, but subject to a restriction that does not allow having the same repeated number in the list (except 0).我需要找到具有已定义长度和已定义大小数字的列表的所有可能组合,但受制于不允许在列表中具有相同重复数字(0 除外)的限制。 Currently I have a recursive code that generates all the combinations, but when trying to create the constraints I lose many options.
目前我有一个生成所有组合的递归代码,但是在尝试创建约束时,我失去了很多选项。 I have tried the options that appear commented to solve it, but it still does not work for me.
我已经尝试了出现评论的选项来解决它,但它仍然对我不起作用。 Thank you in advance for your help.
预先感谢您的帮助。
size=3
l=[0 for x in range(size)]
def recursive(l, index, num, final):
if index == len(l) or num == final:
return
# if num!=0 and num in l:
# return
l[index]=num
print(l)
recursive(l, index+1, 0, final)
recursive(l, index, num+1, final)
recursive(l, 0, 0, 4)
the expected output for a list of size 3 and final number 3 would be something like this对于大小为 3 和最终数字为 3 的列表,预期的 output 将是这样的
[0, 0, 0]
[0, 0, 1]
[0, 0, 2]
[0, 0, 3]
[0, 1, 0]
[0, 1, 2]
[0, 1, 3]
[0, 2, 0]
[0, 2, 1]
[0, 2, 3]
[0, 3, 0]
[0, 3, 1]
[0, 3, 2]
[1, 0, 0]
[1, 0, 2]
[1, 0, 3]
[1, 2, 0]
[1, 2, 3]
[1, 3, 0]
[1, 3, 2]
[2, 0, 0]
[2, 0, 1]
[2, 0, 3]
[2, 1, 0]
[2, 1, 3]
[2, 3, 0]
[2, 3, 1]
[3, 0, 0]
[3, 0, 1]
[3, 0, 2]
[3, 1, 0]
[3, 1, 2]
[3, 2, 0]
[3, 2, 1]
Start with the powerset of the non-zero values (a function for computing the powerset of a list can be found in the itertools
documentation.)从非零值的幂集开始(可以在
itertools
文档中找到用于计算列表的幂集的 function。)
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
>>> list(powerset([1,2,3]))
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
(You could compute the power set including 0, but you would still need to zero-pad the shorter elements, as well as discard (0,1,2,3)
). (您可以计算包括 0 的幂集,但您仍然需要对较短的元素进行零填充,并丢弃
(0,1,2,3)
)。
Each element of the powerset should next be padded with zeros so that they are all the same length.幂集的每个元素接下来应该用零填充,以使它们的长度都相同。
Finally, you want the list of permutations (using itertools.permutations
) of each 0-padded permutation of the original input.最后,您需要原始输入的每个 0 填充排列的排列列表(使用
itertools.permutations
)。
Use itertools.combinations_with_replacement()
, and then filter out the elements with duplicates.使用
itertools.combinations_with_replacement()
,然后过滤掉重复的元素。
def has_duplicates(l):
'''Return True if list has duplicate elements other than 0'''
l = [x in l if x != 0]
return len(l) != len(set(l))
result = [comb for comb in itertools.combinations_with_replacement(l, 3) if not has_duplicates(comb)]
You can make this lazy by using itertools.filterfalse()
;你可以通过使用
itertools.filterfalse()
使它变得懒惰; this way you won't fill up memory with all combinations of a large list.这样你就不会用一个大列表的所有组合来填充 memory 。
result = itertools.filterfalse(has_duplicates, itertools.combinations_with_replacement(l, 3))
Here is a solution based on counters, I am using a base 4 counter:这是一个基于计数器的解决方案,我使用的是 4 进制计数器:
def charcnt(s, a):
ctr = [1 if x == a else 0 for x in s ]
return sum(ctr)
def my_range(start,end,base,step=1):
def Convert(n,base):
string = "0123"
if n < base:
return string[n]
else:
return Convert(n//base,base) + string[n%base]
return (Convert(i,base) for i in range(start,end,step))
# base-10 58 will produce base-4 321
counter = [x.zfill(3) for x in my_range(0, 58, 4)]
result = []
for s in counter:
if charcnt(s, '1') > 1 or charcnt(s, '2') > 1 or charcnt(s, '3') > 1:
continue
else:
result.append(s)
result = [[int(n) for n in list(s)] for s in result]
#print(len(result))
for i in result:
print(i)
Will produce:将产生:
[0, 0, 0]
[0, 0, 1]
[0, 0, 2]
[0, 0, 3]
[0, 1, 0]
[0, 1, 2]
[0, 1, 3]
[0, 2, 0]
[0, 2, 1]
[0, 2, 3]
[0, 3, 0]
[0, 3, 1]
[0, 3, 2]
[1, 0, 0]
[1, 0, 2]
[1, 0, 3]
[1, 2, 0]
[1, 2, 3]
[1, 3, 0]
[1, 3, 2]
[2, 0, 0]
[2, 0, 1]
[2, 0, 3]
[2, 1, 0]
[2, 1, 3]
[2, 3, 0]
[2, 3, 1]
[3, 0, 0]
[3, 0, 1]
[3, 0, 2]
[3, 1, 0]
[3, 1, 2]
[3, 2, 0]
[3, 2, 1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.