Python过滤列表项相对于彼此

dou*_*alg 3 python filtering list filter

假设我有一个元组列表:

fruits = [('apple','red',23),
          ('apple','green',12),
          ('orange','small',12),
          ('orange','large',1)]
Run Code Online (Sandbox Code Playgroud)

如何快速,干净地创建一个新列表,其中包含具有最大数字但对于水果名称唯一的元组.所以理想的结果是:

fruits = [('apple','red',23),
          ('orange','small',12)]
Run Code Online (Sandbox Code Playgroud)

我目前的方法是这样的:

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)]
Run Code Online (Sandbox Code Playgroud)

如果有更好的方法,请告诉我!谢谢.

Mar*_*ers 8

如果您的fruits列表已按水果排序,请使用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))
Run Code Online (Sandbox Code Playgroud)

或者没有发电机:

[max(group, key=itemgetter(2)) for fruit, group in groupby(fruits, itemgetter(0))]
Run Code Online (Sandbox Code Playgroud)

但它可能只是你可以使用发电机,而无需更换fruits批发.

否则使用sorted(fruits, key=(itemgetter(0), -itemgetter(2))并使用groupby抓取每组的第一项:

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))
Run Code Online (Sandbox Code Playgroud)