Py-enthusiast
Py-enthusiast

Reputation: 47

Combinations meeting certain numeric criteria

I need to generate combinations and limit the output to certain combos which meet a numeric criteria associated with the combo. Here are the codes:

import itertools

mylist = [('Beef', 1), ('Pepper', -1),('Onion', 6), ('Green', -1), ('Chicken', 4)]

lst = [item[0] for item in mylist]

combo = []
for i in range(1, 5):
    for tpl in itertools.combinations(lst, i):
        combo.append(tpl)
print(combo)

The code currently generates all possible combinations. I need to limit the result to only those combos where the value is certain numeric value. For example, if my value is 9, then the combo should be generated using "Onion", "Green", and "Chicken", or "Onion", "Chicken", and "Pepper". Because their numeric value adds up to 9 (6+4-1=9). In this case, beef is excluded from the combo generation. How can I do that?

Upvotes: 1

Views: 49

Answers (1)

Tomerikoo
Tomerikoo

Reputation: 19403

Instead of separating the strings to a different list, use the tuples and add a condition on the values and only add the strings that meet the criteria:

import itertools

goal = 9
mylist = [('Beef', 1), ('Pepper', -1),('Onion', 6), ('Green', -1), ('Chicken', 4)]

combo = []
for i in range(1, 5):
    for tpl in itertools.combinations(mylist, i):
        if sum(item[1] for item in tpl) == goal:
            combo.append(tuple(item[0] for item in tpl))
print(combo)

For the case above of goal = 9, this will give:

[('Pepper', 'Onion', 'Chicken'), ('Onion', 'Green', 'Chicken')]

A more "pythonic" way to separate the list of tuples to two lists, is by transposing the list:

    for tpl in itertools.combinations(mylist, i):
        names, values = zip(*tpl)
        if sum(values) == goal:
            combo.append(names)

Upvotes: 2

Related Questions