根据字符串和数值从嵌套列表中删除重复项

4

我有一个这样的列表:

[['john', 14, 'USA'],['john', 27, 'USA'],['paul', 17, 'USA'],['paul', 36, 'USA']]

需要输出以下内容:

[['john', 27, 'USA'],['paul', 36, 'USA']]

这意味着根据位置0删除重复项,但保留位置1中具有更高值的项。
我知道如何使用“set()”在常规列表上删除重复项,但如何应用这两个条件?我正在考虑使用“for”,但由于我将使用的实际列表非常大,所以可能会很慢。
我已经尝试仅按名称删除重复项,但对于保留具有更高值的项感到困惑。
谢谢!

这是一个非常具体的要求,不会有现成的解决方案,你需要循环遍历事物。 - dursk
4个回答

2

您可以使用 itertools.groupby 将元素按第一个索引分组,并使用适当的 keymax 函数来选择基于第二个元素的最大值:

>>> from itertools import groupby
>>> l=[['john', 14, 'USA'], ['john', 27, 'USA'], ['paul', 17, 'USA'], ['paul', 36, 'USA']]
>>> [max(g ,key=lambda x:x[1]) for _,g in groupby(sorted(l),lambda x: x[0])]
[['john', 27, 'USA'], ['paul', 36, 'USA']]

或者更有效率的方法是使用 operators.itemgetter() 而不是 lambda

>>> from operators import itemgetter
>>> [max(g ,key=itemgetter(1)) for _,g in groupby(sorted(l),itemgetter(0))]
[['john', 27, 'USA'], ['paul', 36, 'USA']]

1

我喜欢Kasra的解决方案,但只是为了提供另一种方法:

from collections import defaultdict

l=[['john', 14, 'USA'], ['john', 27, 'USA'], ['paul', 17, 'USA'], ['paul', 36, 'USA']]
key=defaultdict(list)
for n,a,c in l:
    key[(n,c)].append(a)
f_list = [[k[0],max(la),k[1]] for k,la in key.iteritems()]

0

你可以使用OrderedDict,如果我们发现一个子列表具有相同名称且具有较大的第二个子元素,则替换该值:

l = [['john', 14, 'USA'],['john', 27, 'USA'],['paul', 17, 'USA'],['paul', 36, 'USA']]

from collections import OrderedDict
d = OrderedDict()

for sub in l:
    name = sub[0]
    if name in d:
        if sub[1] > d[name][1]:
            d[name] = sub
    else:
        d[name] = sub
print(list(d.values()))

[['john', 27, 'USA'], ['paul', 36, 'USA']]

这是 O(n) 的,因为它不需要对列表进行排序,而排序的复杂度是 n log n,所以这种方法比任何使用排序的方法都更具可扩展性。

如果顺序不重要,普通字典就可以了:

d = {}
for sub in l:
    name = sub[0]
    if name in d:
        if sub[1] > d[name][1]:
            d[name] = sub
    else:
        d[name] = sub
print(d.values())

如果你打算使用operator.itemgetter进行排序,效率会更高。
from operator import  itemgetter    
sorted(l,key=itemgetter(1))

如果你想要对原始列表进行排序:
l.sort(key=itemgetter(1))

0

尝试编写难以理解的 Pythonic 级别代码。

使用列表和字典推导进行排序、合并和重新格式化。

a = [['john', 14, 'USA'],['john', 27, 'USA'],['paul', 17, 'USA'],['paul', 36, 'USA']]

b = sorted(a, key=lambda x: x[0])
c = { x[0] : x[1:len(x)] for x in b }

result = [[n] + c[n] for n in c]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接