为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

侃侃无极 2021-11-23 20:15:00
我有一个字典列表: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但是,我有效地迭代了列表两次,并多次设置字典值。这感觉它可以改进,但我不知道我该怎么做。在给定的约束下,有没有更快的方法来实现这一点?
查看完整描述

3 回答

?
慕的地10843

TA贡献1785条经验 获得超8个赞

假设list1已经按T您可以使用排序itertools.groupby。


from itertools import groupby


li = [

  { '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)]


查看完整回答
反对 回复 2021-11-23
?
当年话下

TA贡献1890条经验 获得超9个赞

假设您的列表已按 排序T,您可以简单地跟踪V一次传递中的最大元素,并在找到时替换最大值:


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 },


unique = {}

for dic in list1:

    key = dic['T']

    found = unique.get(key)


    # If value found and doesn't exceed current maximum, just ignore

    if found and dic['V'] <= found['V']:

        continue


    # otherwise just update normally

    unique[key] = dic


print(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 itemgetter


sorted(list1, key=itemgetter('T'))

operator.itemgetter以上使用与使用相同:


sorted(list1, key=lambda x: x['T'])


查看完整回答
反对 回复 2021-11-23
?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

这是循序渐进的方法。它迭代您的列表一次并构建一个新列表:


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 },

]


# add this step if not already sorted by T

# list1 = sorted(list1, key = lambda x: x["T"]) 


list2 = []

for e in list1:

    t, v, o = e["T"], e["V"], e["O"]


    # we already stored something and same T

    if list2 and list2[-1]["T"] == t:


        # smaller V ?

        if list2[-1]["V"] < v:

            # overwrite dict elements

            list2[-1]["V"] = v

            list2[-1]["O"] = o


    # did not store anything or other T

    else:

        list2.append(e)


print(list2)

输出:


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

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

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


查看完整回答
反对 回复 2021-11-23
  • 3 回答
  • 0 关注
  • 202 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信