Compare two lists of tuples
Solution 1
A set
is a great tool for finding such mismatches:
>>> old = [('ver','1121'),('sign','89'),('address','A45'),('type','00')]
>>> new = [('ver','1121'),('sign','89'),('type','01')]
>>> print('no longer there:', set(old) - set(new))
no longer there: {('type', '00'), ('address', 'A45')}
>>> print('newly added:', set(new) - set(old))
newly added: {('type', '01')}
>>> print('still there:', set(old) & set(new))
still there: {('sign', '89'), ('ver', '1121')}
Solution 2
What about this:
n,o=dict(new),dict(old)
for i in n:
print "{0:10}:{2:8} {3:8} {1}".format(*(("Match","") if o.get(i)==n[i] else ("Mismatch",o.get(i,i)))+ (i,n[i]))
Output:
Mismatch :type 01 00
Match :ver 1121
Match :sign 89
If you need the order, try to use OrderedDict
:
from collections import OrderedDict
n,o=OrderedDict(new),OrderedDict(old)
Solution 3
Sometimes a list comprehension isn't the answer. This may be one of those times. Also, you don't handle the case where a key is present in old
but not in new
- I include that case here, though you can chop out that code if it isn't relevant. You could similarly handle the case of keys missing from new
, but I didn't go that far.
old = [('ver','1121'),('sign','89'),('address','A45'),('type','00')]
new = [('ver','1121'),('sign','89'),('type','01'),("sneaky", 'not there before')]
formatter = "{:12}: {:8} = {}".format
newfmter = "{} (old : {})".format
for (kn, vn) in new:
if any(ko==kn for (ko, vo) in old):
ko, vo = [(ko, vo) for (ko, vo) in old if ko==kn][0]
if vo==vn:
print(formatter("Match", ko, vo))
else:
print(formatter("Mismatch", kn, newfmter(vn, vo)))
else:
print(formatter("New", kn, vn))
Ron
Updated on June 04, 2022Comments
-
Ron over 1 year
old = [('ver','1121'),('sign','89'),('address','A45'),('type','00')] new = [('ver','1121'),('sign','89'),('type','01')]
I need to compare the
new
list againstold
one based on first element of the tuples, and show the difference between whatever elementsnew
list has, so that the output should look like:Match : ver = 1121 Match : sign = 89 Mismatch : type = 01 (old : 00)
I could get all the matching tuples with below list comprehension but could not think beyond it.
my_list = [(a,b) for (a,b) in new for (c,d) in old if ((a==c) and (b==d))] print( my_list)
Please suggest me a way to do it.
EDIT
I am sorry for not being clear on my question , I did not mention one more thing, the keys in the list can be repetitive, meaning the list can be like:
old = [('ver','1121'),('sign','89'),('address','A45'),('type','00'),('ver','sorry')] new = [('ver','1121'),('sign','89'),('type','01'),('ver','sorry)]
UPDATE
Thanks to @holdenweb, I've made some changes to his code and this seems to be providing the expected output, please suggest if there are any flaws.
old = [('ver','1121'),('sign','89'),('address','A45'),('type','00'),('ver','works?')] new = [('ver','1121'),('sign','89'),('type','01'),('ver','This')] formatter = "{:12}: {:8} = {}".format newfmter = "{} (old : {})".format kv_old = [] for i,(kn, vn) in enumerate(new): vo = [(j,(ko,vo)) for j,(ko, vo) in enumerate(old) if (ko==kn) ] for idx,(key,val) in vo: if idx >=i: kv_old = [key,val] break; if kv_old[1]==vn: print(formatter("Match", kv_old[0], kv_old[1])) else: print(formatter("Mismatch", kn, newfmter(vn, kv_old[1])))