Ricardo Francois
Ricardo Francois

Reputation: 792

How to append nested dict value in one list to another?

Suppose I have something like:

list1 = [{"l1_key_1": "l1_value_1", "l1_key_2": "l1_value_2", "l1_key_3": "l1_value_3"}, {...}]
list2 = [{"l2_key_1": "l2_value_1", "l2_key_2": "l2_value_2", "l2_key_3": "l2_value_3"}, {...}]

I'm trying to get an output similar to:

list2 = [{"l2_key_1": ["l1_value_1", "l2_value_1"], "l2_key_2": "l2_value_2", "l2_key_3": "l2_value_3"}, {...}]

I've tried using the zip() and defaultdict methods to help with this but haven't had much luck.

I essentially want to know how I can combine the values of the first and second key for the first element into a list, do the same for the second element, and so on.

Upvotes: 0

Views: 42

Answers (2)

Barmar
Barmar

Reputation: 781004

Make a copies of the dictionaries from list2. Then get the first keys and values from the two dictionaries, combine the values into a list, and replace the first dictionary element with that.

Use a list comprehension to do this for every pair of dictionaries.

def combine_dicts(d1, d2):
    first_value1 = list(d1.values())[0]
    first_key, first_value2 = list(d2.entries())[0]
    new_dict = d2.copy()
    new_dict[first_key] = [first_value1, first_value2]
    return new_dict

result = [combine_dicts(d1, d2) for (d1, d2) in zip(list1, list2)]

This assumes that the two lists are the same length. If not, the extra elements in one of the lists will be discarded.

Upvotes: 1

Tim Ludwinski
Tim Ludwinski

Reputation: 2863

Looking at your output, I see some of the items in the output are lists and some are strings. I consider this an anti-pattern. I think it would be better to have all items as list (even if there is only one or zero items in the list).

Here is code to do what I think you're asking:

from collections import defaultdict

new_list = []
for d1, d2 in zip(list1, list2):
    new_dict = defaultdict(list)
    for k, v in d1.items():
        new_dict[k].append(v)
    for k, v in d2.items():
        new_dict[k].append(v)
    
    new_list.append(new_dict)

One thing to note is that if list1 and list2 are different sizes, zip will only use elements up to the length of the shorter list. If you insist on having both list and string types in the output, the code will be slightly more complex, but I don't see any benefit to doing that.

Upvotes: 0

Related Questions