Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two lists of dicts for multiple key, value pairs?

I have two lists of dicts, one is a modified subset of the other. I would like to get the elements of list_one that don't appear in list_two, based on two keys. Example:

list_one = [{'name': 'alf', 'age': 25},
            {'name': 'alf', 'age': 50},
            {'name': 'cid', 'age': 30}]
list_two = [{'name': 'alf', 'age': 25, 'hair_color': 'brown'},
            {'name': 'cid', 'age': 30, 'hair_color': 'black'}]
desired_list = [{'name': 'alf', 'age': 50}]

How can I accomplish this? I have a feeling it is with some sort of list comprehension, as such:

desired_list = [x for x in list_one if x['name'] != x2['name'] and x['age'] != x2['age'] 
                for all x2 in list_two]
like image 610
x1084 Avatar asked Mar 07 '23 00:03

x1084


1 Answers

I think this is easily done with two comprehensions as:

Code:

have_2 = {(d['name'], d['age']) for d in list_two}
extra = [d for d in list_one if (d['name'], d['age']) not in have_2]

This first creates a set of tuples which we already have, then checks which dicts do not match any of these existing keys.

Test Code:

list_one = [{'name': 'alf', 'age': 25},
            {'name': 'alf', 'age': 50},
            {'name': 'cid', 'age': 30}]
list_two = [{'name': 'alf', 'age': 25, 'hair_color': 'brown'},
            {'name': 'cid', 'age': 30, 'hair_color': 'black'}]

have_2 = {(d['name'], d['age']) for d in list_two}
extra = [d for d in list_one if (d['name'], d['age']) not in have_2]

print(extra)

Results:

[{'name': 'alf', 'age': 50}]
like image 136
Stephen Rauch Avatar answered Apr 08 '23 08:04

Stephen Rauch