Metori
Metori

Reputation: 3

How to limit Python recursive combinations?

I am currently trying to solve a how to get this piece of code to iterate through the different combinations of numbers below to equal 1200. Which works fine however I want the code to limit the numbers it explores and print the combinations with only 5 different numbers.

E.g1 70, 260, 280, 290, 300 = 1200, uses 5 numbers. I want only these combinations.

E.g2 10, 20, 30, 40, 110, 120, 160, 190, 240, 280 = 1200, uses 10 numbers. I don't want combinations with less than five or greater than 5, like this combination.

I don't know python too well, I feel like its a simple thing to do but with my limited coding knowledge I'm stuck.

#!/usr/local/bin/python
from itertools import combinations

def find_sum_in_list(numbers, target):
    results = []
    for x in range(len(numbers)):
        results.extend(
            [   
                combo for combo in combinations(numbers ,x)  
                    if sum(combo) == target    
            ]
    )
    print results

if __name__ == "__main__":
    find_sum_in_list([10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300], 1200)

Thanks for any help. Much appreciated.

Upvotes: 0

Views: 201

Answers (4)

AtlasMeh-ed
AtlasMeh-ed

Reputation: 477

You are on the right track but I don't think you need to do something recursive. I think this works.

from itertools import combinations

def find_sum_in_list(numbers, target, comboSize):
    results = []
    for combo in combinations(numbers, comboSize):
        if sum(combo) == target:
            results.append(combo)
    return results


if __name__ == "__main__":
    numbers = [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300]
    total = 1200
    comboSize = 5
    print find_sum_in_list(numbers, total, comboSize)

Upvotes: 0

jack
jack

Reputation: 2204

You actually have almost what you need. The two lines in your list comprehension are pretty much everything, except for using '5' instead of 'x', as @Eric says. If you use filter to weed out all the combinations that don't have the right sum, then you end up with:

from itertools import combinations

def find_sum_in_list(numbers, target):
    return filter(lambda x: sum(x) == target, combinations(numbers, 5))

if __name__ == '__main__':
    print find_sum_in_list(range(10, 310, 10), 1200)

filter takes a function that takes each element of a list and returns true or false. I've passed into it an anonymous function that returns true only if the list sums to the target.

I also used range to generate your list of numbers, by counting from 10 to 310 by 10. range excludes the last element.

Upvotes: 1

oopcode
oopcode

Reputation: 1962

Well, it is not less recursive than your code, but I think it kind of does what you want.

import itertools

target_list = [
    10, 20, 30, 40, 50, 60, 70, 80, 
    90, 100, 110, 120, 130, 140, 150, 
    160, 170, 180, 190, 200, 210, 220, 
    230, 240, 250, 260, 270, 280, 290, 300
]

target_sum = 1200

def find_sum(target_list, num_elem, target_sum):
    combinations = itertools.combinations(target_list, num_elem)

    for comb in combinations:
        if sum(comb) == target_sum:
            print comb


find_sum(target_list, 5, target_sum)

Upvotes: 0

Eric
Eric

Reputation: 19873

I think that combinations second argument is the number of items to combine. Try passing 5 instead of x

Upvotes: 1

Related Questions