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]
这是一个非常具体的要求,不会有现成的解决方案,您必须循环使用。