Python merge two lists of dictionaries by key

In python 3.5 or higher, you can merge dictionaries in a single statement.

So for python 3.5 or higher, a quick solution would be:

from itertools import zip_longest

l3 = [{**u, **v} for u, v in zip_longest[l1, l2, fillvalue={}]]

print[l3]
#[
#    {'index': 1, 'b': 2, 'c': 4}, 
#    {'index': 2, 'b': 3, 'c': 5}, 
#    {'index': 3, 'green': 'eggs'}
#]

However if the two lists were the same size, you could simply use zip:

l3 = [{**u, **v} for u, v in zip[l1, l2]]

Note: This assumes that the lists are sorted the same way by index, which is stated by OP to not be the case in general.

In order to generalize for that case, one way is to create a custom zip-longest type function which yields values from the two lists only if they match on a key.

For instance:

def sortedZipLongest[l1, l2, key, fillvalue={}]:  
    l1 = iter[sorted[l1, key=lambda x: x[key]]]
    l2 = iter[sorted[l2, key=lambda x: x[key]]]
    u = next[l1, None]
    v = next[l2, None]

    while [u is not None] or [v is not None]:  
        if u is None:
            yield fillvalue, v
            v = next[l2, None]
        elif v is None:
            yield u, fillvalue
            u = next[l1, None]
        elif u.get[key] == v.get[key]:
            yield u, v
            u = next[l1, None]
            v = next[l2, None]
        elif u.get[key] < v.get[key]:
            yield u, fillvalue
            u = next[l1, None]
        else:
            yield fillvalue, v
            v = next[l2, None]

Now if you had the following out of order lists:

l1 = [{"index":1, "b":2}, {"index":2, "b":3}, {"index":3, "green":"eggs"}, 
      {"index":4, "b": 4}]
l2 = [{"index":1, "c":4}, {"index":2, "c":5}, {"index":0, "green": "ham"}, 
      {"index":4, "green": "ham"}]

Using the sortedZipLongest function instead of itertools.zip_longest:

l3 = [{**u, **v} for u, v in sortedZipLongest[l1, l2, key="index", fillvalue={}]]
print[l3]
#[{'index': 0, 'green': 'ham'},
# {'index': 1, 'b': 2, 'c': 4},
# {'index': 2, 'b': 3, 'c': 5},
# {'index': 3, 'green': 'eggs'},
# {'index': 4, 'b': 4, 'green': 'ham'}]

Whereas original method would produce the incorrect answer:

l3 = [{**u, **v} for u, v in zip_longest[l1, l2, fillvalue={}]]
print[l3]
#[{'index': 1, 'b': 2, 'c': 4},
# {'index': 2, 'b': 3, 'c': 5},
# {'index': 0, 'green': 'ham'},
# {'index': 4, 'b': 4, 'green': 'ham'}]

View Discussion

Improve Article

Save Article

  • Read
  • Discuss
  • View Discussion

    Improve Article

    Save Article

    Given two list of dictionaries, the task is to merge these two lists of dictionaries based on some value.

    Method #1: Using defaultdict and extend to merge two list of dictionaries based on school_id.

    from collections import defaultdict

    Input1 = [{'roll_no': ['123445', '1212'], 'school_id': 1},

              {'roll_no': ['HA-4848231'], 'school_id': 2}]

    Input2 = [{'roll_no': ['473427'], 'school_id': 2},

              {'roll_no': ['092112'], 'school_id': 5}]

    temp = defaultdict[list

    for elem in Input1:

        temp[elem['school_id']].extend[elem['roll_no']]

    for elem in Input2:

        temp[elem['school_id']].extend[elem['roll_no']]

    Output = [{"roll_no":y, "school_id":x} for x, y in temp.items[]]

    print[Output]

    Output:

    [{‘school_id’: 1, ‘roll_no’: [‘123445’, ‘1212’]}, {‘school_id’: 2, ‘roll_no’: [‘HA-4848231’, ‘473427’]}, {‘school_id’: 5, ‘roll_no’: [‘092112’]}]

     
    Method #2: Using extend[] only.

    Input1 = [{'roll_no': ['123445', '1212'], 'school_id': 1},

              {'roll_no': ['HA-4848231'], 'school_id': 2}]

    Input2 = [{'roll_no': ['473427'], 'school_id': 2},

              {'roll_no': ['092112'], 'school_id': 5}]

    for elm2 in Input2:

        for elm1 in Input1:

            if elm2['school_id'] == elm1['school_id']:

                elm1['roll_no'].extend[elm2['roll_no']]

                break

        else:

            Input1.append[elm2]

    print[Input1]

    Output:

    [{‘school_id’: 1, ‘roll_no’: [‘123445’, ‘1212’]}, {‘school_id’: 2, ‘roll_no’: [‘HA-4848231’, ‘473427’]}, {‘school_id’: 5, ‘roll_no’: [‘092112’]}]


    How do I merge two dictionaries with the same key in python?

    The simplest way to merge two dictionaries in python is by using the unpack operator[**]. By applying the "**" operator to the dictionary, it expands its content being the collection of key-value pairs.

    How do I merge two lists into a list in python?

    In python, we can use the + operator to merge the contents of two lists into a new list. For example, We can use + operator to merge two lists i.e. It returned a new concatenated lists, which contains the contents of both list_1 and list_2.

    What are 3 different ways to combine 2 lists in python?

    6 Ways to Concatenate Lists in Python.
    concatenation [+] operator..
    Naive Method..
    List Comprehension..
    extend[] method..
    '*' operator..
    itertools.chain[] method..

    Can we merge two dictionaries in python?

    Using | in Python 3.9 In the latest update of python now we can use “|” operator to merge two dictionaries. It is a very convenient method to merge dictionaries.

    Chủ Đề