Python 在排序列表中插入自定义对象

Python 在排序列表中插入自定义对象,python,object,sortedlist,Python,Object,Sortedlist,我实现了一个具有数字属性的对象。我希望根据该属性对这些对象的列表进行排序,而无需在每次插入时运行排序方法。我看了一下对分模块,但我不知道是否也可以将其用于对象。 最好的方法是什么?对分不支持键;阅读本文:出于性能原因,他们也不打算支持这一点。但我认为如果你使用,,,,lt\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu等,它应该会起作用。你可以通过以下方式减少排序的数量 引入一个特殊变量,该变量将显示列表是否已排序和 当

我实现了一个具有数字属性的对象。我希望根据该属性对这些对象的列表进行排序,而无需在每次插入时运行排序方法。我看了一下对分模块,但我不知道是否也可以将其用于对象。
最好的方法是什么?

对分不支持键;阅读本文:出于性能原因,他们也不打算支持这一点。但我认为如果你使用
,lt\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
等,它应该会起作用。

你可以通过以下方式减少排序的数量

  • 引入一个特殊变量,该变量将显示列表是否已排序和
  • 当您需要从列表中获取数据时,如果您的特殊变量告诉您列表已被修改,则对列表进行排序

插入新数据时,应修改特殊变量。

如果实现该方法,可以对自定义对象执行此操作,因为要比较对象

>>> class Foo(object):
...     def __init__(self, val):
...         self.prop = val # The value to compare
...     def __lt__(self, other):
...         return self.prop < other.prop
...     def __repr__(self):
...         return 'Foo({})'.format(self.prop)
...
>>> sorted_foos = sorted([Foo(7), Foo(1), Foo(3), Foo(9)])
>>> sorted_foos
[Foo(1), Foo(3), Foo(7), Foo(9)]
>>> bisect.insort_left(sorted_foos, Foo(2))
>>> sorted_foos
[Foo(1), Foo(2), Foo(3), Foo(7), Foo(9)]
>>类Foo(对象):
...     定义初始值(self,val):
...         self.prop=val#要比较的值
...     定义(自身、其他):
...         返回self.prop>>排序的\ u foos=排序的([Foo(7)、Foo(1)、Foo(3)、Foo(9)])
>>>福斯
[Foo(1)、Foo(3)、Foo(7)、Foo(9)]
>>>左二等分(已排序的左二等分,左二等分)
>>>福斯
[Foo(1)、Foo(2)、Foo(3)、Foo(7)、Foo(9)]

您可以提供list的自定义实现,该实现覆盖进行二进制插入的insert方法。插入元素的时间从O(1)到O(log2(n)),其中n是列表中的元素数

您还可以使用已经实现的实现,例如排序容器[

无论如何,无论您使用什么解决方案,您都必须在对象上实现比较器方法(大于(
\uuu gt\uuuu
)和小于(
\uu lt\uuuu
),这些方法使用此数字属性定义对象的顺序。没有顺序,就无法进行排序

这里有一个例子:

from sortedcontainers import SortedList

class OrderedObject():

    def __init__(self, id, value):
        self.id = id
        self.value = value

    def __gt__(self, other):
        if not isinstance(other,OrderedObject):
            raise Exception("OrderedObject are only comparable to OrderedObject, not to {0}".format(type(other)))
        else:
            return self.value.__gt__(other.value)

    def __lt__(self, other):
        if not isinstance(other,OrderedObject):
            raise Exception("OrderedObject are only comparable to OrderedObject, not to {0}".format(type(other)))
        else:
            return self.value.__lt__(other.value)

    def __repr__(self):
        return "<OrderedObject({0}, {1})>".format(self.id, self.value)

if __name__ == "__main__":
    a = OrderedObject('foo', 1)
    b = OrderedObject('bar', 2)
    c = OrderedObject('-*-', 3)

    mylist = [b,c,a]
    print(mylist)
    mylist.sort()
    print(mylist)

    mylist = SortedList()
    mylist.add(b)
    mylist.add(c)
    mylist.add(a)
    print(mylist)
从sortedcontainers导入SortedList
类OrderedObject():
定义初始化(自我、id、值):
self.id=id
自我价值=价值
定义(自身、其他):
如果不存在(其他,OrderedObject):
引发异常(“OrderedObject只能与OrderedObject比较,而不能与{0}比较”。格式(类型(其他)))
其他:
返回自身值。\uuu gt\uuu(其他值)
定义(自身、其他):
如果不存在(其他,OrderedObject):
引发异常(“OrderedObject只能与OrderedObject比较,而不能与{0}比较”。格式(类型(其他)))
其他:
返回self.value.\uu lt\uu(其他.value)
定义报告(自我):
返回“”。格式(self.id、self.value)
如果名称=“\uuuuu main\uuuuuuuu”:
a=OrderedObject('foo',1)
b=OrderedObject('bar',2)
c=OrderedObject('-*-',3)
mylist=[b,c,a]
打印(mylist)
mylist.sort()
打印(mylist)
mylist=SortedList()
mylist.add(b)
mylist.add(c)
mylist.add(a)
打印(mylist)
这将得出以下结果:

[<OrderedObject(bar, 2)>, <OrderedObject(-*-, 3)>, <OrderedObject(foo, 1)>]
[<OrderedObject(foo, 1)>, <OrderedObject(bar, 2)>, <OrderedObject(-*-, 3)>]
SortedList([<OrderedObject(foo, 1)>, <OrderedObject(bar, 2)>, <OrderedObject(-*-, 3)>])
[,]
[, ]
分类列表([,])

NB:我并没有以任何方式对分类容器库进行引用。

你已经查过了。这个配方是在二分模块本身中链接的。你真的需要整个列表进行排序吗?或者你只是想轻松地访问最小(或最大)?如果是的话,你可能想考虑使用堆(参见Python的HeAPQ模块)。.可能的副本