繁体   English   中英

Dict.setdefault插入排序到列表中

[英]Dict.setdefault insert sorted into a list

我想知道是否有一种方法可以使用类似lambda的样式附加到排序的字典列表字段。

例:

a = {}
a.setdefault("foo", []).append(2)
a.setdefault("foo", []).append(1)
{'foo': [2, 1]}

有没有办法insert in sorted order进行insert in sorted order如使用a["foo"].bisect.insort(a, -1) ,这样我以后不需要调用sort?

您只需要在Pythons标准库中:

import bisect
from collections import defaultdict


def add(dd, key, value):
    bisect.insort_left(dd[key], value)


a = defaultdict(list)
add(a, "foo", 3)
add(a, "foo", 2)
add(a, "foo", 1)
add(a, "foo", 3)
add(a, "foo", 2)
add(a, "foo", 1)

assert a["foo"] == sorted(a["foo"])
print(a)

如果你想要一个lambda:

add = lambda dd, key, value: bisect.insort_left(dd[key], value)

在使用sort之后的性能方面,运行时应该比使用bisect.insort_left更快。 在这两种情况下,运行时复杂度为O(n log n),但函数调用开销应导致不同的绝对运行时间。

您可以使用collections.defaultdict ,使用一些SortedList实现(使用pip install sortedcontainers下载,但还有其他):

import collections
from sortedcontainers import SortedList

a = collections.defaultdict(SortedList)
a["foo"].add(2)
a["foo"].add(1)
print(a)

结果:

defaultdict(<class 'sortedcontainers.sortedlist.SortedList'>, {'foo': SortedList([1, 2])})

如果你有很多代码需要重构,你可以通过append来覆盖add

请注意,它也适用于setdefault ,但更麻烦:

a = {}
a.setdefault("foo", SortedList()).add(2)
a.setdefault("foo", SortedList()).add(1)

(并且在很多元素上执行此操作具有创建SortedList()对象的缺点,以防密钥不存在)

虽然您可以使用辅助函数执行此操作:

def list_append(lst, item):
    lst.append(item)
    return lst

a = {}
list_append(a.setdefault("foo", []), 2).sort()
list_append(a.setdefault("foo", []), 1).sort()

但我肯定会建议你尝试其他数据结构,比如heapq

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM