Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Filter List Items Relative to Each Other

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.

like image 935
dougalg Avatar asked Jun 03 '26 18:06

dougalg


2 Answers

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))
like image 166
Martijn Pieters Avatar answered Jun 06 '26 07:06

Martijn Pieters


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)]
like image 26
eumiro Avatar answered Jun 06 '26 07:06

eumiro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!