Reputation: 23
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
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
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
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
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