It's intended to compare two lists in Python which are made up of dict elements, in each dict element, there are two keys. Below the sample is provided.
A=[{'id':'u2s8Et','value':'David'},{'id':'u2s0PW','value':'Linda'},......]
B=[{'id':'u2s8Et','value':'David'},{'id':'u2s7PA','value':'Steven'},......]
It's expected to get which elements are only available in list A and which elements in list A differ from the one in list B. Is there any existing module can be adopted to compare?
The method assertListEqual in unittest module is close to the expectation but some module more comprehensive is preferred.
The main issue is that dict
s are not hashable. Because each one of them has the same keys, though, we can convert them to a hashable type, like a tuple
.
def parse(values):
return set(map(tuple, map(dict.values, values)))
>>> parse(A)
>>> {('u2s0PW', 'Linda'), ('u2s8Et', 'David')}
We can now use set
operations to compare the elements of each.
In [6]: parse(A).difference(parse(B))
Out[6]: {('u2s0PW', 'Linda')}
In [7]: parse(A).intersection(parse(B))
Out[7]: {('u2s8Et', 'David')}
set.difference
will find the items that are in A
but not B
, and set.intersection
will find the items that are in both A
and B
.
Edit: Since your dict
s all follow the same format, you could consider using a namedtuple
, as well.
In [1]: from collections import namedtuple
In [2]: entry = namedtuple("Entry", ("id", "value"))
In [3]: A = [{'id':'u2s8Et', 'value':'David'}, {'id':'u2s0PW', 'value':'Linda'}]
...: B = [{'id':'u2s8Et', 'value':'David'}, {'id':'u2s7PA', 'value':'Steven'}]
...:
In [4]: def parse_to_entry(values):
...: return {entry(d["id"], d["value"]) for d in values}
...:
In [5]: parse_to_entry(A)
Out[5]: {Entry(id='u2s0PW', value='Linda'), Entry(id='u2s8Et', value='David')}
In [6]: parse_to_entry(A).difference(parse_to_entry(B))
Out[6]: {Entry(id='u2s0PW', value='Linda')}
In [7]: parse_to_entry(A).intersection(parse_to_entry(B))
Out[7]: {Entry(id='u2s8Et', value='David')}