简体   繁体   中英

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?

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)]

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)]

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM