Перестановки имеет о принятии упорядоченного множества вещей и перенести эти вещи вокруг (т.е. изменение порядка). Ваш вопрос: сочетает вещей из вашего списка.
Теперь простой способ перечисления комбинаций - это сопоставление записей из вашего списка с битами в количестве. Например, допустим, что если бит # 0 установлен (т.е. 1), тогда число lst[0]
участвует в комбинации, если бит # 1 установлен, то lst[1]
участвует в комбинации и т. Д. Таким образом, номера в диапазоне 0 <= n < 2**(len(lst))
идентифицируют все возможные комбинации lst
членов, включая пустую (n = 0
) и все lst
(n = 2**(len(lst)) - 1
).
Вам нужны только комбинации из 2-х элементов или более, то есть только те комбинации идентификаторов, у которых есть как минимум два ненулевых бита в их двоичном представлении. Вот как их идентифицировать:
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]
Следующий шаг - извлечь комбинацию элементов списка, идентифицированных идентификатором комбинации.Это очень просто, благодаря силе списковых:
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
http://docs.python.org/library/itertools.html#itertools.permutations имеет эквивалентный код 'itertools.permutations' – SilentGhost
Вы уверены, что хотите' 636 + 1636' и '1636 + 636' в качестве отдельных элементов ? – kennytm
Я думаю, что это больше * комбинаций *, чем * перестановки *. –