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

时间:2015-01-07 21:31:24

标签: python python-3.x

我有一个这样的清单:

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

需要获得输出:

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

这意味着删除基于位置0的重复项,但保留位置1中值较高的重复项。

我知道如何使用set()删除常规列表上的重复项,但如何应用这两个条件呢?我正在考虑使用for,但我可能会非常慢,因为我将使用的真实列表非常大。

我已经尝试仅通过名称删除重复项,但我对于保留具有更高价值的副本感到困惑。

谢谢!

4 个答案:

答案 0 :(得分:1)

您可以使用itertools.groupby按照第一个索引和max函数对元素进行分组,并使用正确的key根据第二个元素选择最大值:

>>> 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 :(得分: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()]

答案 2 :(得分: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列表进行排序,因此这比使用已排序的任何方法都要好。

如果顺序无关紧要,正常的dict就可以了:

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

答案 3 :(得分: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]