0

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.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
ImmuneMoon
  • 27
  • 7
  • Welcome to Stack Overflow. "the keys in list1[] dicts are the same as each other, and the keys in list2[] dicts are also the same as each other" This description doesn't match the example data, and it also isn't clear what should happen if the dicts have more than one key in them. The problem description is too vague, and also not focused - there is a lot to do here. Please read [ask], and note well that this is **not a discussion forum** - we require a **specific, answerable question**, and "Any help is appreciated." [does not qualify](https://meta.stackoverflow.com/questions/284236). – Karl Knechtel Sep 18 '22 at 23:51
  • Anyway, please try to think about the problem, and break it down into logical steps. For example, if you only had one dict (not in a list) from each of the actual lists, would you be able to compute the corresponding output dict? Do you know how to pair up the dicts from the two lists? Do you know how to repeat a calculation for each of those pairs? If you put those steps together, does it solve the problem? If not, why not? If you don't know one or more of those things, then each one is a **separate question**, and each can be addressed by existing duplicate questions. – Karl Knechtel Sep 18 '22 at 23:52
  • I appreciate you taking the time to explain what you have, with all due respect however, I believe the description was accurate to the given dict lists? The keys are in fact the same as each other in the first dict list and the same in the second dict list, the second dict list has different dict keys from the first list but I don't believe what I said was incorrect? I did clarify in edit that they should extend indefinitely and I believe multiplying in parallel assumes the dict lists will always be the same length and operate the same way? I apologize if that's an incorrect assumption. – ImmuneMoon Sep 19 '22 at 00:12
  • In any case, I will try and be more pedantic in the future when possible. – ImmuneMoon Sep 19 '22 at 00:13
  • 1
    "the second dict list has different dictionary keys from the first list but I don't believe what I said was incorrect?" Oh, that was ambiguous. I thought you meant "the first dict in the first list has the same keys as the first dict in the second list; the second dict in the first list has the same keys as the second dict in the second list; etc." – Karl Knechtel Sep 19 '22 at 00:15
  • In this case, the problem is still unclear. It seems that you have keys `"l1_key"` in every dict from the first list, and `"l2_key"` in every dict from the second list. What I do not understand: **what is the rule that tells you** to multiply `"l1_key"` values by `"l2_key"` values? – Karl Knechtel Sep 19 '22 at 00:15
  • "the keys in list1[] dicts are the same as each other, and the keys in list2[] dicts are also the same as each other" I guess I could see why that's a little ambiguous? But I thought it was clear given the example. As for the rule, I thought "I'm trying to multiply key values in parallel dictionaries across 2 lists of dictionaries" was clarifying the rule of how they would operate, but again, I will try to be more pedantic in the future, apologies. – ImmuneMoon Sep 19 '22 at 00:23
  • "I'm trying to multiply key values in parallel dictionaries across 2 lists of dictionaries" **Which** value in the dictionary from the first list, with **which** value in the dictionary from the second list? **Why**? – Karl Knechtel Sep 19 '22 at 00:48
  • **{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**. They are that way "Because of how I'm pulling information from some SQL databases(.)". – ImmuneMoon Sep 19 '22 at 00:59
  • No. I mean, why does l1_key multiply with l2_key? Why does l1_key *not* multiply with l3_key, or some other key? What is the *relationship between* the names `l1_key` and `l2_key`, that tells you to multiply them together? – Karl Knechtel Sep 19 '22 at 01:06
  • They are two values I need multiplied in parallel with one another so I can calculate SQL data they're pulled from and pass "(`multiplied[]` to a) Jinja (template, and) add values to a (data readout) table". – ImmuneMoon Sep 19 '22 at 01:13
  • Why is `l2_key` the value that you need to multiply with `l1_key`? How do you know that `l2_key` is the name of the value that should be multiplied with the `l1_key` value? If I tell you that I think that the `l1_key` value should be multiplied with the `l3_key` value instead, why am I wrong? – Karl Knechtel Sep 19 '22 at 01:14
  • Because the two values are related in data I'm pulling from SQL databases. And because that's what needs to happen. Why should you want to multiply the first and the third when it's stated that's not what needs to be done? I have work to do and I don't see a need to further clarify. If you don't understand then I'm sorry, I've explained this as best I can. – ImmuneMoon Sep 19 '22 at 01:20

3 Answers3

1

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}]
Rahul K P
  • 15,740
  • 4
  • 35
  • 52
1

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}]
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • I'm a little confused with whats happening here ``` v1 = (v for d in list1 for v in d.values()) v2 = (v for d in list2 for v in d.values()) ``` would you mind clarifying? I've never used zip before either – ImmuneMoon Sep 18 '22 at 23:40
  • 1
    With `v1 = (v for d in list1 for v in d.values())` I'm creating a generator that yields every value from each dictionary in the `list1`. The `v2` is doing the same for `list2`. Then I use `zip()` to *tie* these two values together. – Andrej Kesely Sep 19 '22 at 00:07
0
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.

Lost_coder
  • 94
  • 8