1

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)]
1
  • 1
    Sorry, what's the question here exactly? Commented Mar 21, 2024 at 20:29

1 Answer 1

1

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)],
]
Sign up to request clarification or add additional context in comments.

3 Comments

Walrus? Ugh. Chaining! (Or abs.)
Also, one trick I like to use is to use two combinations in parallel, one for the names and one for the values. Then it's simply sum(vs). Makes your solution about twice as fast.
Andrej Kesely, Simply sensational. Thank you very much

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.