How would you go about multiplying values across multiple dict lists in python

Viewed 59

I'm trying to multiply key values in parallel dictionaries across 2 lists of dictionaries like:

list1: [{'l1_key': 1}, {'l1_key': 2}]
list2: [{'l2_key': 28.64}, {'l2_key': 303.35}]

(the keys in list1[] dicts are the same as each other, and the keys in list2[] dicts are also the same as each other because of how I'm pulling information from some SQL databases) to get a product of the two inside another dict list like so:

multiplied: [{'product': 28.64}, {'product': 606.7}]

I'm using the latest python version and flask, with the goal of looping through this list in Jinja to add values to a table, so these keys are the same too.

So far I've tried looping through both to add each val to a dict and then append that value to a list of dicts after multiplying using:


list1: [{'l1_key': 1}, {'l1_key': 2}]
list2: [{'l2_key': 28.64}, {'l2_key': 303.35}]
...
...
values = {}
multiplied = []

# Loops along list1[]
for i in range(len(list1)):

    # Updates values{}
    values.update({"value1": list1[i]['l1_key']})
    print('values: ', values)

    # Loops through list2[]
    for x in range(len(list2)):

        # Updates values{}
        values.update({"value2": list2[x]['l2_key']})
        print('product: ', multiplied)

        # Assigns values to variables
        num1 = values['value1']
        num2 = values['value2']

        # Multiplies and appends to multiplied[]
        multiplied.append({"product": num1 * num2})
        print('multiplied: ', multiplied)

        # Clears values{} for next loop
        values.clear()

but it only works for the first set of values and not the second, and I get a keyerror:

TERMINAL OUTPUT
----------------
values:  {'value1': 1}
values:  {'value1': 1, 'value2': 28.64}
multiplied:  []
multiplied:  [{'product': 28.64}]
values:  {'value2': 303.35}
multiplied:  [{'product': 28.64}]
...
in line xxx
    num2 = values['value1']
KeyError: 'value1'

I'm guessing cause of how the loops are structured, value 1 isn't getting data from the second l1 key but I'm still relatively new to programming and not sure how to go about fixing it, or if there's maybe a better solution to this. Any help is appreciated.

Edit: I should also clarify that the amount of dicts in each initial list has to be able to grow indefinitely and still provide a list of products for the table the information is being inserted into.

Edit 2: For example, l1_key should multiply with l2_key in the order they are listed within each dict list. list1[] and list2[] will also always be the same length and the keys that need to be multiplied will always match at each index in the listed order across both lists in parallel.

3 Answers

You can do it with zip,

In [1]: [{'product': l[0]['l1_key']*l[1]['l2_key']} for l in zip(list_1, list_2)]
Out[1]: [{'product': 28.64}, {'product': 606.7}]

Zip will combine the values list_1 and list_2 as a list of tuples, This will be the result of zip.

In [2]: list(zip(list_1, list_2))
Out[2]: [({'l1_key': 1}, {'l2_key': 28.64}), ({'l1_key': 2}, {'l2_key': 303.35})]

Edit

An attempt without using the hardcoded key values, Assumption: The dictionary will have only one value

v1 = list(map(lambda x:list(x.values())[0], list_1))
v2 = list(map(lambda x:list(x.values())[0], list_2))
list(map(lambda x:{'product': x[0]*x[1]}, zip(v1,v2)))
#Result
[{'product': 28.64}, {'product': 606.7}]

Another solution, that isn't using names of keys in dictionaries:

list1 = [{"l1_key": 1}, {"l1_key": 2}]
list2 = [{"l2_key": 28.64}, {"l2_key": 303.35}]

v1 = (v for d in list1 for v in d.values())
v2 = (v for d in list2 for v in d.values())

out = [{"product": a * b} for a, b in zip(v1, v2)]
print(out)

Prints:

[{'product': 28.64}, {'product': 606.7}]
a = [{'l1_key': 1}, {'l1_key': 2}]
b = [{'l2_key': 28.64}, {'l2_key': 303.35}]
result = list()
for i in range(len(a)):
    dictinary = dict()
    dictinary["product"] = a[i][next(iter(a[i]))] * b[i][next(iter(b[i]))]
    result.append(dictinary)

you could do something like this.

Related