J'ai une liste de numéros, par ex.
numbers = [1, 2, 3, 7, 7, 9, 10]
Comme vous pouvez le voir, les chiffres peuvent apparaître plusieurs fois dans cette liste.
J'ai besoin d'obtenir toutes les combinaisons de ces nombres qui ont une somme donnée, par exemple 10
.
Les éléments des combinaisons ne peuvent pas être répétés, mais chaque élément de numbers
doit être traité de manière unique, cela signifie par exemple les deux 7
dans la liste représentent différents éléments avec la même valeur.
L'ordre est sans importance, de sorte que [1, 9]
et [9, 1]
sont la même combinaison.
Il n'y a aucune restriction de longueur pour les combinaisons, [10]
est aussi valide que [1, 2, 7]
.
Comment puis-je créer une liste de toutes les combinaisons répondant aux critères ci-dessus?
Dans cet exemple, ce serait [[1,2,7], [1,2,7], [1,9], [3,7], [3,7], [10]]
Vous pouvez utiliser itertools pour parcourir toutes les combinaisons de toutes les tailles possibles et filtrer tout ce qui ne correspond pas à 10:
import itertools
numbers = [1, 2, 3, 7, 7, 9, 10]
result = [seq for i in range(len(numbers), 0, -1) for seq in itertools.combinations(numbers, i) if sum(seq) == 10]
print result
Résultat:
[(1, 2, 7), (1, 2, 7), (1, 9), (3, 7), (3, 7), (10,)]
Malheureusement, c'est quelque chose comme la complexité O (2 ^ N), donc il ne convient pas pour des listes d'entrée plus grandes, disons, 20 éléments.
La solution proposée par @kgoodrick est géniale mais je pense qu'elle est plus utile en tant que générateur:
def subset_sum(numbers, target, partial=[], partial_sum=0):
if partial_sum == target:
yield partial
if partial_sum >= target:
return
for i, n in enumerate(numbers):
remaining = numbers[i + 1:]
yield from subset_sum(remaining, target, partial + [n], partial_sum + n)
list(subset_sum([1, 2, 3, 7, 7, 9, 10], 10))
donne [[1, 2, 7], [1, 2, 7], [1, 9], [3, 7], [3, 7], [10]]
.
Cette question a été posée auparavant, voir la réponse @msalvadores ici . J'ai mis à jour le code python donné pour s'exécuter dans python 3:
def subset_sum(numbers, target, partial=[]):
s = sum(partial)
# check if the partial sum is equals to target
if s == target:
print("sum(%s)=%s" % (partial, target))
if s >= target:
return # if we reach the number why bother to continue
for i in range(len(numbers)):
n = numbers[i]
remaining = numbers[i + 1:]
subset_sum(remaining, target, partial + [n])
if __name__ == "__main__":
subset_sum([3, 3, 9, 8, 4, 5, 7, 10], 15)
# Outputs:
# sum([3, 8, 4])=15
# sum([3, 5, 7])=15
# sum([8, 7])=15
# sum([5, 10])=15
Cela marche...
from itertools import combinations
def SumTheList(thelist, target):
arr = []
p = []
if len(thelist) > 0:
for r in range(0,len(thelist)+1):
arr += list(combinations(thelist, r))
for item in arr:
if sum(item) == target:
p.append(item)
return p