Dictionary Comparison/Conditional check in Python
Asked Answered
W

3

6

I have two list of dictionaries in the format:

list1 = [
    {"time": "2024-01-29T18:32:24.000Z", "value": "abc"},
    {"time": "2024-01-30T19:47:48.000Z", "value": "def"},
    {"time": "2024-01-30T19:24:20.000Z", "value": "ghi"}
]

list2 = [
    {"time": "2024-01-30T18:34:44.000Z", "value": "xyz"},
    {"time": "2024-01-30T19:47:48.000Z", "value": "pqr"},
    {"time": "2024-01-30T19:24:20.000Z", "value": "jkl"}
]

Requirement : I need to compare value of "time" key of each dictionary in list1 with "time" key of each dictionary in list2 and if they are equal, will need to form a key value pair dictionary for subsequent lookups.
In the above, list1 and list2 have 2 dictionaries with same time :
"2024-01-30T19:47:48.000Z"
"2024-01-30T19:24:20.000Z"
I need to combine value of these 2 to form output as below :

Output :

{"def" : "pqr", "ghi" : "jkl"}

using itertools.product function , i am able to list as below so far but not in the key value pair dictionary as required .

import itertools

list1 = [{"time": "2024-01-29T18:32:24.000Z", "value": "abc"}, {"time": "2024-01-30T19:47:48.000Z", "value": "def"}, {"time": "2024-01-30T19:24:20.000Z", "value": "ghi"}]
list2 = [{"time": "2024-01-30T18:34:44.000Z", "value": "xyz"}, {"time": "2024-01-30T19:47:48.000Z", "value": "pqr"}, {"time": "2024-01-30T19:24:20.000Z", "value": "jkl"}]

output = [f"{x['value']} : {y['value']}"  if x['time'] == y['time'] else None for (x, y) in itertools.product(list1, list2)]
print(output)

Current Output :

[None, None, None, None, 'def : pqr', None, None, None, 'ghi : jkl']

I'm wondering if i can use lambda function to achieve output as : {"def" : "pqr", "ghi" : "jkl"}
Any help or suggestions is appreciated.

Warga answered 31/1 at 14:30 Comment(2)
Can a time occur multiple times in a list?Inhabitancy
Using itertools.product will make it O(np), which can be a problem is your lists are huge; Andrej Kesely's solution is O(n + p) which is more efficient.Tropology
Q
4

dict comprehension has an if clause (at the end), to also filter out elements, like this:

output = {x['value']: y['value'] for x, y in itertools.product(list1, list2) if x['time'] == y['time']}

Output:

{'def': 'pqr', 'ghi': 'jkl'}

Quass answered 31/1 at 14:34 Comment(0)
M
6

I'd create temporary index to ease the search:

list1 = [
    {"time": "2024-01-29T18:32:24.000Z", "value": "abc"},
    {"time": "2024-01-30T19:47:48.000Z", "value": "def"},
    {"time": "2024-01-30T19:24:20.000Z", "value": "ghi"},
]

list2 = [
    {"time": "2024-01-30T18:34:44.000Z", "value": "xyz"},
    {"time": "2024-01-30T19:47:48.000Z", "value": "pqr"},
    {"time": "2024-01-30T19:24:20.000Z", "value": "jkl"},
]

tmp = {d["time"]: d for d in list1}

out = {}
for d in list2:
    if d["time"] in tmp:
        out[tmp[d["time"]]["value"]] = d["value"]

print(out)

Prints:

{'def': 'pqr', 'ghi': 'jkl'}
Mintz answered 31/1 at 14:36 Comment(0)
L
5

Instead of a list comprehension, use a dictionary comprehension to get keys and values directly:

>>> {x['value'] : y['value']  if x['time'] == y['time'] else None for (x, y) in itertools.product(list1, list2)}
{'abc': None, 'def': None, 'ghi': 'jkl'}

Then, move the conditional to the comprehension, so it skips the Nones:

>>> {x['value']: y['value'] for (x, y) in itertools.product(list1, list2) if x['time'] == y['time']}
{'def': 'pqr', 'ghi': 'jkl'}
Landahl answered 31/1 at 14:35 Comment(0)
Q
4

dict comprehension has an if clause (at the end), to also filter out elements, like this:

output = {x['value']: y['value'] for x, y in itertools.product(list1, list2) if x['time'] == y['time']}

Output:

{'def': 'pqr', 'ghi': 'jkl'}

Quass answered 31/1 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.