Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于字符串和值从嵌套列表中删除重复项_Python_Python 3.x - Fatal编程技术网

Python 基于字符串和值从嵌套列表中删除重复项

Python 基于字符串和值从嵌套列表中删除重复项,python,python-3.x,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()删除常规列表中的重复项,但如何应用这两个条件?我在想一些关于的,但我可能会很慢,因为我将使用的真正列表非常大 我已经试着只按

我有这样一份清单:

[['john', 14, 'USA'],['john', 27, 'USA'],['paul', 17, 'USA'],['paul', 36, 'USA']]
并且需要作为输出获取:

[['john', 27, 'USA'],['paul', 36, 'USA']]
这意味着基于位置0删除重复项,但将值较高的保留在位置1

我知道如何使用
set()
删除常规列表中的重复项,但如何应用这两个条件?我在想一些关于的
,但我可能会很慢,因为我将使用的真正列表非常大

我已经试着只按名字删除重复项,但我对保留高值项感到困惑


谢谢

您可以使用
itertools.groupby
按第一个索引对元素进行分组,并使用带有适当
键的
max
函数根据第二个元素选择最大值:

>>> 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']]
或者,作为一种更有效的方法,您可以使用
操作符.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']]

如果我们发现具有相同名称的子列表具有较大的第二个子元素,则可以使用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())
如果要使用
运算符进行排序,itemgetter
将更有效:

from operator import  itemgetter    
sorted(l,key=itemgetter(1))
如果要对原始列表进行排序:

l.sort(key=itemgetter(1))

我喜欢Kasra的解决方案,但jsut想给出另一种方法:

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

在不可理解的层面上考验我的手

使用列表和字典理解我排序、合并和重新格式化

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]

这是一个非常具体的要求,不会有现成的解决方案,您必须循环使用。