我有一个包含15个数字的列表,我需要编写一些代码来生成这些数字的所有32,768种组合。

我已经找到了一些代码(通过谷歌搜索),显然做了我正在寻找的,但我发现代码相当不透明,并谨慎使用它。而且我觉得肯定有更优雅的解决方案。

我唯一想到的就是循环十进制整数1-32768并将其转换为二进制,并使用二进制表示作为筛选器来挑选适当的数字。

有人知道更好的办法吗?使用map(),也许?


当前回答

flag = 0
requiredCals =12
from itertools import chain, combinations

def powerset(iterable):
    s = list(iterable)  # allows duplicate elements
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

stuff = [2,9,5,1,6]
for i, combo in enumerate(powerset(stuff), 1):
    if(len(combo)>0):
        #print(combo , sum(combo))
        if(sum(combo)== requiredCals):
            flag = 1
            break
if(flag==1):
    print('True')
else:
    print('else')

其他回答

这一行代码给出了所有的组合(如果原始列表/set包含n个不同的元素,则在0到n个元素之间),并使用本机方法itertools.combination:

Python 2

from itertools import combinations

input = ['a', 'b', 'c', 'd']

output = sum([map(list, combinations(input, i)) for i in range(len(input) + 1)], [])

Python 3

from itertools import combinations

input = ['a', 'b', 'c', 'd']

output = sum([list(map(list, combinations(input, i))) for i in range(len(input) + 1)], [])

输出将是:

[[],
 ['a'],
 ['b'],
 ['c'],
 ['d'],
 ['a', 'b'],
 ['a', 'c'],
 ['a', 'd'],
 ['b', 'c'],
 ['b', 'd'],
 ['c', 'd'],
 ['a', 'b', 'c'],
 ['a', 'b', 'd'],
 ['a', 'c', 'd'],
 ['b', 'c', 'd'],
 ['a', 'b', 'c', 'd']]

在网上试试吧:

http://ideone.com/COghfX

这种方法可以很容易地移植到所有支持递归的编程语言中(没有itertools,没有yield,没有列表理解):

def combs(a):
    if len(a) == 0:
        return [[]]
    cs = []
    for c in combs(a[1:]):
        cs += [c, c+[a[0]]]
    return cs

>>> combs([1,2,3,4,5])
[[], [1], [2], [2, 1], [3], [3, 1], [3, 2], ..., [5, 4, 3, 2, 1]]

看看itertools.combination:

itertools.combinations (iterable, r) 返回元素的r长度子序列 输入迭代对象。 组合是按字典排序顺序发出的。那么,如果 Input iterable已排序,则 组合元组将在 排序顺序。

从2.6开始,电池包括在内!

下面是一个使用递归的例子:

>>> import copy
>>> def combinations(target,data):
...     for i in range(len(data)):
...         new_target = copy.copy(target)
...         new_data = copy.copy(data)
...         new_target.append(data[i])
...         new_data = data[i+1:]
...         print new_target
...         combinations(new_target,
...                      new_data)
...                      
... 
>>> target = []
>>> data = ['a','b','c','d']
>>> 
>>> combinations(target,data)
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'b', 'c', 'd']
['a', 'b', 'd']
['a', 'c']
['a', 'c', 'd']
['a', 'd']
['b']
['b', 'c']
['b', 'c', 'd']
['b', 'd']
['c']
['c', 'd']
['d']

如果你不想使用组合库,这里是解决方案:

nums = [1,2,3]
p = [[]]
fnl = [[],nums]

for i in range(len(nums)):
    for j in range(i+1,len(nums)):
        p[-1].append([i,j])

for i in range(len(nums)-3):
    p.append([])
    for m in p[-2]:
        p[-1].append(m+[m[-1]+1])

for i in p:
    for j in i:
        n = []
        for m in j:
            if m < len(nums):
                n.append(nums[m])
        if n not in fnl:
            fnl.append(n)

for i in nums:
    if [i] not in fnl:
        fnl.append([i])

print(fnl)

输出:

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