old = [('ver','1121'),('sign','89'),('address','A45'),('type','00')]
new = [('ver','1121'),('sign','89'),('type','01')]
I need to compare the new
list against old
one based on first element of the tuples, and show the difference between whatever elements new
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])))
Method #1 : Using == operator This is the simplest and elegant way to perform this task. It also checks for equality of tuple indices with one other.
Rules for comparing tuples Compare the n-th items of both tuple (starting with the zero-th index) using the == operator. If both are equal, repeat this step with the next item. For two unequal items, the item that is “less than” makes the tuple, that contains it, also “less than” the other tuple.
The set() function and == operator Python set() function manipulate the list into the set without taking care of the order of elements. Besides, we use the equal to operator (==) to compare the data items of the list.
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')}
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))
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With