Permutations sont à prendre un ensemble ordonné des choses et le déplacement de ces choses (par exemple pour changer). Votre question porte sur combinaisons de choses de votre liste. Maintenant, un moyen facile d'énumérer des combinaisons est de mapper les entrées de votre liste en bits dans un nombre. Par exemple, supposons que si le bit # 0 est défini (ie 1), alors le numéro lst[0]
participe à la combinaison, si le bit # 1 est défini, alors lst[1]
participe à la combinaison, etc. De cette façon, les nombres dans la plage 0 <= n < 2**(len(lst))
identifient tous combinaisons possibles de lst
membres, y compris un vide (n = 0
) et l'ensemble lst
(n = 2**(len(lst)) - 1
).
Vous n'avez besoin que de combinaisons de 2 éléments ou plus, c'est-à-dire uniquement les ID de combinaison qui ont au moins deux bits différents de zéro dans leur représentation binaire. Voici comment les identifier:
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]
L'étape suivante consiste à extraire une combinaison de membres de liste identifiés par un identifiant de combinaison.C'est facile, grâce à la puissance de la liste compréhensions:
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]
Maintenant, nous allons faire un générateur qui produit toutes les sommes, ainsi que leurs représentations de chaîne:
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)
Et, enfin, nous allons l'utiliser:
>>> 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 a un code équivalent à 'itertools.permutations' – SilentGhost
Etes-vous sûr de vouloir que '636 + 1636' et' 1636 + 636' soient des éléments distincts ? – kennytm
Je pense que c'est plus * combinaisons * que * permutations *. –