<p>排列是指将一组有序的事物集合起来,并将这些事物移动(即改变顺序)。你的问题是关于你清单上的东西的组合。在</p>
<p>现在,枚举组合的一种简单方法是将列表中的条目映射到数字中的位。例如,假设如果位0被设置(即1),那么数字<code>lst[0]</code>参与组合,如果位1被设置,那么<code>lst[1]</code>参与组合,等等。这样,范围<code>0 <= n < 2**(len(lst))</code>中的数字标识{<cd4>}成员的所有可能组合,包括空的(<code>n = 0</code>)和整个{<cd4>}(<code>n = 2**(len(lst)) - 1</code>)的所有可能组合。在</p>
<p>您只需要2个或更多项的组合,即只需要那些在二进制表示中至少有两个非零位的组合id。以下是如何识别这些:</p>
<pre><code>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]
</code></pre>
<p>下一步是提取由组合id标识的列表成员的组合。由于列表理解的强大功能,这很容易做到:</p>
^{pr2}$
<p>现在让我们制作一个生成所有和及其字符串表示的生成器:</p>
<pre><code>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)
</code></pre>
<p>最后,让我们使用它:</p>
<pre><code>>>> 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
</code></pre>