Python过滤列表项相对于彼此

时间:2012-12-18 07:58:51

标签: python list filter filtering

假设我有一个元组列表:

fruits = [('apple','red',23),
          ('apple','green',12),
          ('orange','small',12),
          ('orange','large',1)]

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

fruits = [('apple','red',23),
          ('orange','small',12)]

我目前的方法是:

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

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

4 个答案:

答案 0 :(得分: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))

或者说没有发电机:

[max(group, key=itemgetter(2)) for fruit, group in groupby(fruits, itemgetter(0))]

但可能只是使用生成器而不替换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))

答案 1 :(得分:3)

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

返回

[('apple', 'red', 23), ('orange', 'small', 12)]

答案 2 :(得分:0)

f = {}
for item in fruits:
    if item[0] not in f or item[2] > f[item[0]][2]:
        f[item[0]] = item

filtered_list = f.values()

答案 3 :(得分:0)

     python 3.2
     from itertools import groupby

 1.    [max(v,key=lambda x:x[2])for _,v in groupby(fruits,key=lambda x:x[0])]

没有itertools groupby函数:

  2.  [max([(f,c,n) for f,c,n in fruit if f==k],key=lambda x:x[2])
                                        for k in set([i[0] for i in fruit])]


  3.  [max([i for i in fruit if i[0]==v],key=lambda x:x[2]) for v in set(k[0]for k in fruit)]


  4. loop method

   newlist=[]
   newset=set(i[0] for i in fruit)
   for i in newset:
        t=(0,0,0)
        for l in fruit:
           if i==l[0] and l[2]>t[2]:
                    t=l
        d.append(t)