Search code examples
pythonpython-3.xlisttuplessubtraction

How to subtract the last number/element in a separate list of tuples having multiple criteria?


samplelist1 = [('A', 'Pass', 20), ('A', 'Failed', 5), ('B', 'Pass', 10), ('B', 'Failed', 5) ]

samplelist2 = [('A', 'Pass', 2), ('A', 'Failed', 1), ('B', 'Failed', 2)]

# Expected Output: result = [('A', 'Pass', 18), ('A', 'Failed', 4), ('B', 'Pass', 10), ('B', 'Failed', 3) 

Can I Still use this code ??? Using this code as my reference

from collections import defaultdict

d = defaultdict(int)
for letter, status, value in samplelist:
    d[(letter, status)] += value
res = [key + (val,) for key, val in d.items()] # convert to required format
print(res) 

Solution

  • Your current code won't work, because it uses samplelist, but your data only contains samplelist1 and samplelist2. I'm assuming this was a error and you forgot to include the loop where you iterate the sample lists.

    In any case, I don't think you need a defaultdict. Just traverse samplelist1, set the values in a dictionary, then traverse samplelist2, and deduct the values from the dictionary.

    samplelist1 = [('A', 'Pass', 20), ('A', 'Failed', 5), ('B', 'Pass', 10), ('B', 'Failed', 5) ]
    
    samplelist2 = [('A', 'Pass', 2), ('A', 'Failed', 1), ('B', 'Failed', 2)]
    
    d = {}
    for x, y, z in samplelist1:
        d[x, y] = z
    
    for x, y, z in samplelist2:
        d[x, y] -= z
    
    result = [(k1, k2, v) for (k1, k2), v in d.items()]
    
    print(result)
    

    If we really want to use a defaultdict, we could modify your approach to first collect the items in a list, then minus the first item from the second item(if more than one element exists):

    from collections import defaultdict
    
    samplelist1 = [('A', 'Pass', 20), ('A', 'Failed', 5), ('B', 'Pass', 10), ('B', 'Failed', 5) ]
    
    samplelist2 = [('A', 'Pass', 2), ('A', 'Failed', 1), ('B', 'Failed', 2)]
    
    d = defaultdict(list)
    for samplelist in (samplelist1, samplelist2):
        for x, y, z in samplelist:
            d[x, y].append(z)
    
    result = [(k1, k2, v[0] - v[1] if len(v) > 1 else v[0]) for (k1, k2), v in d.items()]
    
    print(result)
    

    Output:

    [('A', 'Pass', 18), ('A', 'Failed', 4), ('B', 'Pass', 10), ('B', 'Failed', 3)]