Let's say I have a list of tuples:
fruits = [('apple','red',23),
('apple','green',12),
('orange','small',12),
('orange','large',1)]
How can I quickly and cleanly create a new list with the tuples that have the largest numbers but unique to fruit name. So the ideal result would be:
fruits = [('apple','red',23),
('orange','small',12)]
My current method is this:
def check_fruit(fruit, a_list):
for item in a_list:
if fruit[0] == item[0] and fruit[2] < item[2]:
return False
return True
filtered_list = [fruit for fruit in fruits if check_fruit(fruit, fruits)]
Please let me know if there's a better way! Thanks.
If your fruits list is already sorted by fruit, use itertools.groupby:
from itertools import groupby
from operator import itemgetter
def fruitfilter(fruits):
for fruit, group in groupby(fruits, key=itemgetter(0)):
yield max(group, key=itemgetter(2))
fruits = list(fruitfilter(fruits))
Or in short without a generator:
[max(group, key=itemgetter(2)) for fruit, group in groupby(fruits, itemgetter(0))]
but it could be you could just use the generator without replacing fruits wholesale.
Otherwise use sorted(fruits, key=(itemgetter(0), -itemgetter(2)) and use groupby to grab the first item of each group:
def fruitfilter(fruits):
sortedfruits = sorted(fruits, key=(itemgetter(0), -itemgetter(2)))
for fruit, group in groupby(sortedfruits, key=itemgetter(0)):
yield next(group)
fruits = list(fruitfilter(fruits))
import itertools as it
fruits = [('apple','red',23),
('apple','green',12),
('orange','small',12),
('orange','large',1)]
uniq_max = [next(v) for k,v in it.groupby(sorted(fruits, key=lambda x:(x[0], -x[2])), key=lambda x:x[0])]
returns
[('apple', 'red', 23), ('orange', 'small', 12)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With