3

假设我有一个元组列表:

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

4 回答 4

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))
于 2012-12-18T08:03:38.450 回答
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)]
于 2012-12-18T08:03:00.227 回答
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()
于 2012-12-18T08:05:05.927 回答
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)
于 2012-12-18T15:02:07.827 回答