I have two list
s of dict
s, 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]
I think this is easily done with two comprehensions as:
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 tuple
s which we already have, then checks which dict
s do not match any of these existing keys.
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)
[{'name': 'alf', 'age': 50}]
Yet another possible solution:
>>> list(filter(lambda x: not any([set(x.items()).issubset(y.items()) for y in list_two]), list_one))
[{'age': 50, 'name': 'alf'}]
or:
>>> s2 = [set(i.items()) for i in list_two]
>>> list(filter(lambda x: not any([set(x.items()).issubset(y) for y in s2]), list_one))
[{'age': 50, 'name': 'alf'}]
The advantage of this approach is that it does not need to know the "keys" ('age' and 'name') present in both dictionary sets.
Use this:-
new_list = [i for i,j in zip(list_one,list_two) if i['name']!=j['name'] and i['age']!=j['age']]
print (new_list)
[{'name': 'alf', 'age': 50}]
An efficient way would be to convert your two structures to dicts, keyed by the two values, then create the result dict:
key = lambda dct: (dct['name'], dct['age'])
d1 = { key(dct): dct for dct in list_one }
d2 = { key(dct): dct for dct in list_two }
desired_d = { k:v for k,v in d1.items() if k not in d2 }
print(desired_d)
print(desived_d.values())
diff = [
e for e in list_one
if (e['name'], e['age']) not in set((e['name'], e['age']) for e in list_two)
]
print diff
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.