I have a list of numbers, e.g.
numbers = [1, 2, 3, 7, 7, 9, 10]
As you can see, numbers may appear more than once in this list.
I need to get all combinations of these numbers that have a given sum, e.g. 10
.
The items in the combinations may not be repeated, but each item in numbers
has to be treated uniquely, that means e.g. the two 7
in the list represent different items with the same value.
The order is unimportant, so that [1, 9]
and [9, 1]
are the same combination.
There are no length restrictions for the combinations, [10]
is as valid as [1, 2, 7]
.
How can I create a list of all combinations meeting the criteria above?
In this example, it would be [[1,2,7], [1,2,7], [1,9], [3,7], [3,7], [10]]
Find cells combination that equal a given sum with Solver Add-in. If you are confused with above method, Excel contains a Solver Add-in feature, by using this add-in, you can also identify the numbers which total amount equals a given value.
First, we take an empty list 'res' and start a loop and traverse each element of the given list of integers. In each iteration, pop the element, store it in 'num', find remaining difference for sum K, and check if the difference exists in the given list or not.
Remember, the formula to calculate combinations is nCr = n! / r! * (n - r)!, where n represents the number of items, and r represents the number of items being chosen at a time. Let's look at an example of how to calculate a combination.
Add a Custom Column to and name it List1. Enter the formula =List1. Expand out the new List1 column and then Close & Load the query to a table. The table will have all the combinations of items from both lists and we saved on making a custom column in List1 and avoided using a merge query altogether!
You could use itertools to iterate through every combination of every possible size, and filter out everything that doesn't sum to 10:
import itertools numbers = [1, 2, 3, 7, 7, 9, 10] target = 10 result = [seq for i in range(len(numbers), 0, -1) for seq in itertools.combinations(numbers, i) if sum(seq) == target] print(result)
Result:
[(1, 2, 7), (1, 2, 7), (1, 9), (3, 7), (3, 7), (10,)]
Unfortunately this is something like O(2^N) complexity, so it isn't suitable for input lists larger than, say, 20 elements.
The solution @kgoodrick offered is great but I think it is more useful as a generator:
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))
yields [[1, 2, 7], [1, 2, 7], [1, 9], [3, 7], [3, 7], [10]]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With