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

Question:

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.

Asked By: ImmuneMoon

||

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}]
Answered By: Rahul K P

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}]
Answered By: Andrej Kesely
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.

Answered By: Lost_coder
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.