2012-12-18 46 views
3

比方说,我有一个元组列表:Python的筛选器列表项相互

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

请让我知道如果有一个更好的办法!谢谢。

+2

是否顺序的结果出现问题? – NPE

+3

你的'fruits'列表是否已经按水果分类? –

+1

是的,它已经按水果名称排序了,我希望理想的结果是按照相同的顺序。 – dougalg

回答

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

@ Martjin Pieters - 你的第二个函数语法似乎有点不正确(第二行),并且你没有使用已分类的水果。 – root

+0

@root:ack,c&p&忘记错误。谢谢! –

+0

您的第二个生成器在第二行缺少右括号。这似乎是最好的答案,并且有效!非常感谢! – dougalg

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