假设我有一个元组列表:
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)]
如果有更好的方法,请告诉我!感谢。
答案 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)