Timmay
Timmay

Reputation: 23

I have 2 lists of tuples, how can I print the difference between the second element of the tuples while leaving the first element the same?

Example, I have two lists:

[('Joe', 10), ('Tim', 14), ('Toby', 20)]

[('Joe', 8), ('Tim', 18), ('Toby', 12)]

I want it to print:

[('Joe', 2), ('Tim', -4), ('Toby', 8)]

What is the best way to do this?

Upvotes: 1

Views: 58

Answers (4)

dawg
dawg

Reputation: 103824

You can use a list comprehension:

l1=[('Joe', 10), ('Tim', 14), ('Toby', 20)]
l2=[('Joe', 8), ('Tim', 18), ('Toby', 12)]

>>> [(t1[0],t1[1]-t2[1]) for t1,t2 in zip(l1,l2)]
[('Joe', 2), ('Tim', -4), ('Toby', 8)]

You can add a test to make sure that the first part of the tuple is the same if appropriate:

[(t1[0],t1[1]-t2[1]) for t1,t2 in zip(l1,l2) if t1[0]==t2[0]]

But wim's version using a counter is the most robust if you have lists that might have mismatched tuples.

Upvotes: 0

wim
wim

Reputation: 362687

Consider using a collections.Counter, which features a "subtraction" version of dict.update. For example:

>>> L1 = [('Joe', 10), ('Tim', 14), ('Toby', 20)]
>>> L2 = [('Joe', 8), ('Tim', 18), ('Toby', 12)]
>>> from collections import Counter
>>> c1 = Counter(dict(L1))
>>> c1.subtract(Counter(dict(L2)))
>>> print(list(c1.items()))
[('Joe', 2), ('Tim', -4), ('Toby', 8)]

Upvotes: 2

rdas
rdas

Reputation: 21275

I think you want to subtract the values if the names match. Try this:

first = [('Joe', 10), ('Tim', 14), ('Toby', 20)]
second = [('Joe', 8), ('Tim', 18), ('Toby', 12)]

access_dict = {}  # used for matching the names
for name, value in first:
    access_dict[name] = value  # add to matcher dict

for name, value in second:
    if name in access_dict:  # skip if corresponding name was not in first
        access_dict[name] = access_dict[name] - value  # subtract value

print(list(access_dict.items()))

Output:

[('Joe', 2), ('Tim', -4), ('Toby', 8)]

Note: this does not preserve the order of the names

Upvotes: 0

E. Ducateme
E. Ducateme

Reputation: 4248

An approach is to zip the contents and then parse each zipped pair, doing the math and name extraction at that time.

zip will produce an iterable that will generate a pair of items, zippered together from each of the input items... If you were to look at these pairs, the would look something like this:

(('Joe', 10), ('Joe', 8))
(('Tim', 14), ('Tim', 18))
(('Toby', 20), ('Toby', 12))

With each item paired, it is fairly straightforward to then manipulate OR process each pair.

>>> l1 = [('Joe', 10), ('Tim', 14), ('Toby', 20)] 
>>> l2 = [('Joe', 8), ('Tim', 18), ('Toby', 12)]                                                                                                                                                                   
>>> new_list = []                                                                                                                                                                                                  

>>> for element1, element2 in zip(l1, l2): 
...     new_list.append((element1[0], element1[1] - element2[1])) 
...                                                                                                                                                                                                                
>>> new_list                                                                                                                                                                                                       
[('Joe', 2), ('Tim', -4), ('Toby', 8)]

Upvotes: 0

Related Questions