I have a set of variables each containing an array of chosen integers:
var_1 = [0.5, 1, 2]
var_2 = [0.5, 1, 4, 7.5]
var_3 = [1, 1.5, 3.5, 4, 5.5, 10]
I would like to choose each number from each of the stated variables above and add them together until the first combination of those variables falls within a specified win range such as:
winning_range = [15-20]
So the above winning_range would be the first combination that falls between integers 15-20
I would like to print the winning combination as a dictionary with each combination piece along with a dictionary key showing the value of the numbers added up:
{var_1 = 2, var_2= 7.5, var_3= 10, total= 19.5}
What would be the most efficient way to obtain this through python?
CodePudding user response:
Maybe not the most efficient, but pretty human readable
var_1 = [0.5, 1, 2]
var_2 = [0.5, 1, 4, 7.5]
var_3 = [1, 1.5, 3.5, 4, 5.5, 10]
winning_range = [15, 20] # Converting to a list for [min, max]
result = {}
for v1 in var_1:
for v2 in var_2:
for v3 in var_3:
if v1 v2 v3 in range(winning_range[0], winning_range[1]):
result = {"var_1": v1, "var_2": v2, "var_3": v3}
print(result)
# Output
# {'var_1': 2, 'var_2': 7.5, 'var_3': 5.5}
I should add you specified the first combination, so this solution is literally attempting them sequentially.
CodePudding user response:
You can use a recursive generator function:
r = [15, 20]
var_1 = [0.5, 1, 2]
var_2 = [0.5, 1, 4, 7.5]
var_3 = [1, 1.5, 3.5, 4, 5.5, 10]
def combos(d, c = [], s = 0):
if not d and r[0] <= s and r[-1] >= s:
yield (c, s)
elif d:
for i in filter(lambda x:r[-1] >= x s, d[0]):
yield from combos(d[1:], c=c [i], s=s i)
print(list(combos([var_1, var_2, var_3])))
Output:
[([0.5, 7.5, 10], 18.0), ([1, 4, 10], 15), ([1, 7.5, 10], 18.5), ([2, 4, 10], 16), ([2, 7.5, 5.5], 15.0), ([2, 7.5, 10], 19.5)]
Here, at each recursive call, potential values from a var
list are only included if the running sum plus the value does not exceed the maximum threshold, thus minimizing the total number of recursive calls needed. While list(combos([var_1, var_2, var_3]))
loads all the possibilities into memory, you can use next
to grab only the first result:
vals, total = next(combos([var_1, var_2, var_3]))