0

I have a working solution but I was wondering if there is a more elegant or more 'pythonic' solution. I have a list of dictionaries. Every dictionary has 4 keys. I need to check if the values of 3 keys of one dictionary are identical to the key values of the next dictionary. The code below, marked with '#This code' is the code in question. Is there a more elegant or more compact way to do this?

I am fairly new to Python, and this is my first post here. Thank you.

from operator import itemgetter
from pprint import pprint

lst = [{ "fname" : "John", "lname" : "Doe", "age" : 20, "amount":200 },
{ "fname" : "Sue" , "lname" : "Jones", "age" : 17, "amount":800 },
{ "fname" : "Rick", "lname" : "West" , "age" : 25, "amount":280 },
{ "fname" : "Sue" , "lname" : "Jones", "age" : 17, "amount":120 },
{ "fname" : "John", "lname" : "Doe"  , "age" : 20, "amount":100 }]

#Sort list
lst_sorted = sorted(lst, key=itemgetter('fname', 'lname', 'age'))
pprint(lst_sorted)
for i in range(0, len(lst_sorted)-1):
    print(lst_sorted[i])
    print(lst_sorted[i+1])
        #This code
    if ( lst_sorted[i]['fname'] == lst_sorted[i+1]['fname'] ) and \
       ( lst_sorted[i]['lname'] == lst_sorted[i+1]['lname'] ) and \
       ( lst_sorted[i]['age']   == lst_sorted[i+1]['age'] ):
        #/This code/
        print('equal')
    else:
        print('not equal')
Ray Johnson
  • 97
  • 1
  • 9

1 Answers1

1

First, if you are just comparing sequential items from your sorted list, you could just use zip on two slices:

for a, b in zip(lst_sorted[:-1], lst_sorted[1:]):
    # do things

The zip operator will produce tuples of the corresponding elements in any number of iterables.

The [:-1] slice will grab everything except the last element, and the [1:] slice will grab everything except the first, effectively offsetting them by one. You can read about slices here.

Then, for the comparison, you could use the all operator to short-circuit the check on the keys which won't do the entire comparison if one fails. all(condition_1, ..., condition_n) is equivalent to condition_1 and ... and condition_n:

for a, b in zip(lst_sorted[:-1], lst_sorted[1:]):
    print(a, b)
        #This code
    if all(a.get(k) == b.get(k) for k in ['fname', 'lname', 'age']):
        #/This code/
        print('equal')
    else:
        print('not equal')

Where dict.get will prevent you from having a KeyError in case one is missing

C.Nivs
  • 12,353
  • 2
  • 19
  • 44