Testing difference between lists of tuples and constructing a dict of results

I have two lists of tuples where tuple[0] is a unique_id and tuple[1] is a value I want to compare between tuples that match on unique_id. The lists may differ in length but the tuples will be of the same format.

list1 = [(uid,value1,value2),...]
list2 = [(uid,value1,value2),...]

How would I best get to a dictionary:

{uid:value1,...}

where uid matches but value1 does not, populating the dict with value1 from list2?

Example:

list1 = [(1,A,z),(2,B,y),(3,C,z),(4,D,w),(6,F,x)]
list2 = [(1,G,z),(2,B,x),(3,D,q),(5,F,z)]

result = {1:G,3:D}

My attempt thus far:

dict1 = {tup[0]:tup[1:] for tup in list1}
dict2 = {tup[0]:tup[1:] for tup in list2}

result = {}
for k in set(dict1) & set(dict2):
  if dict1[k][0] != dict2[k][0]:
    result[k] = dict2[k][0]

I am hoping there is a more efficient or cleaner way of getting to the result.

1 answer

  • answered 2018-12-05 20:05 Daniel Mesejo

    Assuming the list are sorted by uid and of the same length, this should work:

    list1 = [(1,'A','z'),(2,'B','y'),(3,'C','z'),(4,'D','w')]
    list2 = [(1,'G','z'),(2,'B','x'),(3,'D','q'),(5,'F','z')]
    
    result = {k2 : v2 for (k1, v1, _), (k2, v2, _) in zip(list1, list2) if k1 == k2 and v1 != v2}
    
    print(result)
    

    Output

    {1: 'G', 3: 'D'}
    

    If the conditions above do not hold, you could do:

    list1 = [(1, 'A', 'z'), (2, 'B', 'y'), (3, 'C', 'z'), (4, 'D', 'w')]
    list2 = [(1, 'G', 'z'), (2, 'B', 'x'), (3, 'D', 'q'), (5, 'F', 'z')]
    
    d1 = {k1: v1 for k1, v1, _ in list1}
    d2 = {k2: v2 for k2, v2, _ in list2}
    
    result = {k2: v2 for k2, v2 in d2.items() if k2 in d1 and d1[k2] != v2}
    print(result)
    

    Output

    {1: 'G', 3: 'D'}