pythonrecursionpython-itertools

Combination of values ​using dictionary or list


I'm trying to write a function that takes the values ​​in a list or dictionary and returns the combination of an approximate value. I adjusted the code found here:

from itertools import takewhile, combinations, permutations, product

def findPairs(lst, K):
    for i in range(1,len(lst),1):
        print([pair for pair in combinations(lst, i) if sum(pair) >= K-0.01 and sum(pair) <= K+0.01])

When running this code with the parameters:

K = 1282.66
print(findPairs(lst, K))

I get the following response

[(263.09, 883.58, 75.75, 29.88, 30.36), (263.09, 883.58, 75.75, 29.88, 30.37)]

The combinations are correct and the pairs that were reported have been found. However, I wanted to go into a little more detail because on a daily basis I would have many pairs for the same price as the base would be much larger. I soon thought if I could use something like a list or dictionary, like this:

lst = [['A1',263.09], ['A2',883.58],['A3', 75.75], ['A4',29.88],['A5',30.36],['A6',30.37]['A7',590.72],['A8', 162.45], ['A9',47.25], ['A10',252.98], ['A11',69.57],['A12', 20.24]]

Getting the following response:

[(A1,A2, A3, A4,A5),(263.09, 883.58, 75.75, 29.88, 30.36)], [(A1,A2, A3, A4,A6),(263.09, 883.58, 75.75, 29.88, 30.37)]

Solution

  • IIUC, you can do:

    from itertools import combinations
    
    def findPairs(lst, K):
        out = [
            comb
            for i in range(1, len(lst))
            for comb in combinations(lst, i)
            if (s := sum(v for _, v in comb)) >= K - 0.01 and s <= K + 0.01
        ]
    
        return [list(zip(*subl)) for subl in out]
    
    lst = [
        ["A1", 263.09],
        ["A2", 883.58],
        ["A3", 75.75],
        ["A4", 29.88],
        ["A5", 30.36],
        ["A6", 30.37],
        ["A7", 590.72],
        ["A8", 162.45],
        ["A9", 47.25],
        ["A10", 252.98],
        ["A11", 69.57],
        ["A12", 20.24],
    ]
    
    K = 1282.66
    print(findPairs(lst, K))
    

    Prints:

    [
        [("A1", "A2", "A3", "A4", "A5"), (263.09, 883.58, 75.75, 29.88, 30.36)],
        [("A1", "A2", "A3", "A4", "A6"), (263.09, 883.58, 75.75, 29.88, 30.37)],
    ]