用规则统一字典列表的最快方法?

我有一个字典列表:


list1 = [

  { 'T': 1234, 'V': 10, 'O': 1 },

  { 'T': 2345, 'V': 50, 'O': 5 },

  { 'T': 2345, 'V': 30, 'O': 3 },

  { 'T': 3456, 'V': 40, 'O': 91 },

]

我需要对这些进行唯一排序:


T 应该是独一无二的

哪个 dictV较大应该优先

哪个应该产生:


[

  {'T': 1234, 'V': 10, 'O': 1}, 

  {'T': 2345, 'V': 50, 'O': 5}, 

  {'T': 3456, 'V': 40, 'O': 91}

]

我想出了这个:


interm = {o['T']: o for o in list1}

for o in list1:

  if o['V'] > interm[o['T']]['V']:

    interm[o['T']] = o

但是,我有效地迭代了列表两次,并多次设置字典值。这感觉它可以改进,但我不知道我该怎么做。


在给定的约束下,有没有更快的方法来实现这一点?


侃侃无极
浏览 203回答 3
3回答

慕的地10843

假设list1已经按T您可以使用排序itertools.groupby。from itertools import groupbyli = [  { 'T': 1234, 'V': 10, 'O': 1 },  { 'T': 2345, 'V': 50, 'O': 5 },  { 'T': 2345, 'V': 30, 'O': 3 },  { 'T': 3456, 'V': 40, 'O': 91 },]output = [max(group, key=lambda d: d['V'])          for _, group in groupby(li, key=lambda d: d['T'])]print(output)# [{'T': 1234, 'V': 10, 'O': 1}, {'T': 2345, 'V': 50, 'O': 5}, {'T': 3456, 'V': 40, 'O': 91}]如果不是,groupby仍然可以使用 withsort以实现 O(nlogn) 解决方案order_by_t = lambda d: d['T']li.sort(key=order_by_t)output = [max(group, key=lambda d: d['V'])          for _, group in groupby(li, key=order_by_t)]

当年话下

假设您的列表已按 排序T,您可以简单地跟踪V一次传递中的最大元素,并在找到时替换最大值:list1 = [&nbsp; &nbsp; { 'T': 1234, 'V': 10, 'O': 1 },&nbsp; &nbsp; { 'T': 2345, 'V': 50, 'O': 5 },&nbsp; &nbsp; { 'T': 2345, 'V': 30, 'O': 3 },&nbsp; &nbsp; { 'T': 3456, 'V': 40, 'O': 91 },]&nbsp;unique = {}for dic in list1:&nbsp; &nbsp; key = dic['T']&nbsp; &nbsp; found = unique.get(key)&nbsp; &nbsp; # If value found and doesn't exceed current maximum, just ignore&nbsp; &nbsp; if found and dic['V'] <= found['V']:&nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; # otherwise just update normally&nbsp; &nbsp; unique[key] = dicprint(list(unique.values()))# [{'T': 1234, 'V': 10, 'O': 1}, {'T': 2345, 'V': 50, 'O': 5}, {'T': 3456, 'V': 40, 'O': 91}]如果您的列表不能保证按 排序T,您可以预先应用排序 withT作为排序key:from operator import itemgettersorted(list1, key=itemgetter('T'))operator.itemgetter以上使用与使用相同:sorted(list1, key=lambda x: x['T'])

蝴蝶不菲

这是循序渐进的方法。它迭代您的列表一次并构建一个新列表:list1 = [&nbsp; { 'T': 1234, 'V': 10, 'O': 1 },&nbsp; { 'T': 2345, 'V': 50, 'O': 5 },&nbsp; { 'T': 2345, 'V': 30, 'O': 3 },&nbsp; { 'T': 3456, 'V': 40, 'O': 91 },]# add this step if not already sorted by T# list1 = sorted(list1, key = lambda x: x["T"])&nbsp;list2 = []for e in list1:&nbsp; &nbsp; t, v, o = e["T"], e["V"], e["O"]&nbsp; &nbsp; # we already stored something and same T&nbsp; &nbsp; if list2 and list2[-1]["T"] == t:&nbsp; &nbsp; &nbsp; &nbsp; # smaller V ?&nbsp; &nbsp; &nbsp; &nbsp; if list2[-1]["V"] < v:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # overwrite dict elements&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list2[-1]["V"] = v&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list2[-1]["O"] = o&nbsp; &nbsp; # did not store anything or other T&nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; list2.append(e)print(list2)输出:[{'T': 1234, 'O': 1, 'V': 10},&nbsp;&nbsp;{'T': 2345, 'O': 5, 'V': 50},&nbsp;&nbsp;{'T': 3456, 'O': 91, 'V': 40}]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python