我有一个输入数字列表,例如
671.00
1,636.00
436.00
9,224.00
我希望生成所有可能的总和,并为其输入ID,例如:
671.00 + 1,636.00 = 2,307.00
671.00 + 436.00 = 1,107.00
671.00 + 9,224.00 = 9,224.00
671.00 + 1,636.00 + 436.00 = 2,743.00
...
我想用Python做 我目前的限制是: a)我现在正在学习python(这是想法的一部分) b)我将不得不使用Python 2.5.2(没有intertools)
我想我找到了一段可能有用的代码:
def all_perms(str):
if len(str) <=1:
yield str
else:
for perm in all_perms(str[1:]):
for i in range(len(perm)+1):
#nb str[0:1] works in both string and list contexts
yield perm[:i] + str[0:1] + perm[i:]
(来自these guys)
但我不确定如何在我的建议中使用它。 有人可以提供一些提示和帮助代码吗?
欢呼声,
F。
答案 0 :(得分:3)
排列是关于采取有序的一组事物并移动这些东西(即改变顺序)。您的问题是关于列表中组合的事情。
现在,枚举组合的一种简单方法是将列表中的条目映射到数字中的位。例如,假设如果设置了位#0(即1),则数字lst[0]
参与组合,如果设置了位#1,则lst[1]
参与组合等。方式,范围0 <= n < 2**(len(lst))
中的数字标识lst
成员的所有可能组合,包括空成员(n = 0
)和整个lst
(n = 2**(len(lst)) - 1
)。< / p>
您只需要2项或更多项的组合,即只需要在其二进制表示中至少有两个非零位的组合ID。以下是如何识别这些:
def HasAtLeastTwoBitsSet(x) :
return (x & (x-1)) != 0
# Testing:
>>> [x for x in range(33) if HasAtLeastTwoBitsSet(x)]
[3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
下一步是提取由组合ID标识的列表成员的组合。由于列表推导的强大功能,这很容易:
def GetSublistByCombination(lst, combination_id) :
res = [x for (i,x) in enumerate(lst) if combination_id & (1 << i)]
return res
# Testing:
>>> GetSublistByCombination([0,1,2,3], 1)
[0]
>>> GetSublistByCombination([0,1,2,3], 3)
[0, 1]
>>> GetSublistByCombination([0,1,2,3], 12)
[2, 3]
>>> GetSublistByCombination([0,1,2,3], 15)
[0, 1, 2, 3]
现在让我们创建一个生成所有总和的生成器及其字符串表示:
def IterAllSums(lst) :
combinations = [i for i in range(1 << len(lst)) if HasAtLeastTwoBitsSet(i)]
for comb in combinations :
sublist = GetSublistByCombination(lst, comb)
sum_str = '+'.join(map(str, sublist))
sum_val = sum(sublist)
yield (sum_str, sum_val)
最后,让我们使用它:
>>> for sum_str, sum_val in IterAllSums([1,2,3,4]) : print sum_str, sum_val
1+2 3
1+3 4
2+3 5
1+2+3 6
1+4 5
2+4 6
1+2+4 7
3+4 7
1+3+4 8
2+3+4 9
1+2+3+4 10
答案 1 :(得分:0)
下面的代码生成给定列表的所有“子集”(空集除外),即返回列表列表。
def all_sums(l): #assumes that l is non-empty
if len(l)==1:
return ([[l[0]]])
if len(l)==0:
return []
result = []
for i in range(0,len(l)):
result.append([l[i]])
for p in all_sums(l[i+1:]):
result.append([l[i]]+p)
return result
现在你也可以为输出写一个简短的函数doit
:
def doit(l):
mylist = all_sums(l)
print mylist
for i in mylist:
print str(i) + " = " + str(sum(i))
doit([1,2,3,4])
答案 2 :(得分:0)
使用itertools(Python&gt; = 2.6)将是:
from itertools import *
a=[1,2,3,4]
sumVal=[tuple(imap(sum,combinations(a,i))) for i in range(2,len(a)+1)]