简体   繁体   English

保持可变元素的排序列表是最新的

[英]Keep sorted list of mutable elements up to date

I can use sorted or list.sort in python to sort a list that was not sorted before.我可以在 python 中使用sortedlist.sort对之前未排序的列表进行排序。

If I want my list to remain sorted as I add elements in it, I can useSortedList from the sortedcontainers module.如果我希望我的列表在添加元素时保持排序,我可以使用sortedcontainers模块中的SortedList

However, I find no ready-to-use way to keep this list sorted as elements mutate within it.但是,我发现没有现成的方法可以这个列表排序为元素在其中发生变异。

from sortedcontainers import SortedList

a = SortedList([], key=len) # sort elements by their length.
a.add([3,3,3]) # add in..
a.add([1]) # .. random..
a.add([2,2]) # .. order.
print(a) # [[1], [2, 2], [3, 3, 3]] still sorted, okay.

# Now, mutate one element.
a[0].append(1)
a[0].append(1)
print(a) # [[1, 1, 1], [2, 2], [3, 3, 3]] not sorted, not okay.

I understand that SortedList is not responsible to track changes it contained items and to keep the sorting up to date.我了解SortedList不负责跟踪它包含的项目的更改并保持排序是最新的。

How do I update the sorting, then?那么如何更新排序呢?
Is there a message I can send to a so it is aware that I have made a change at index 0 and it reconsiders the location of item 0 , like a.update_sorting_of(0) .是否有我可以发送给a的消息,以便它知道我在索引0处进行了更改,并且它会重新考虑项目0的位置,例如a.update_sorting_of(0)
Is there another data structure dedicated to this?是否有另一种数据结构专门用于此?
Should I write it and optimize it myself?我应该自己编写并优化它吗?
Should I work around it and a.add(a.pop(0)) instead?我应该解决它并使用a.add(a.pop(0))吗?
How would this workaround compare to a dedicated solution?与专用解决方案相比,此解决方法如何?

I can safely assume that mutating a[0] has not triggered any changes in other elements in my case (or else I would just a.sort(key=len) the whole thing).我可以安全地假设在我的情况下,变异a[0]没有触发其他元素的任何变化(否则我只会a.sort(key=len)整个事情)。

There is no mechanism to do what you want.没有机制可以做你想做的事。 Even if you were to resort a list after mutating an element, it'd have O(nlogn) complexity.即使你在改变一个元素后使用一个列表,它的复杂度也是 O(nlogn)。 But because add() uses bisect behind the scenes, it only has O(logn).但是因为add()在幕后使用了 bisect,所以它只有 O(logn)。 So it's better to do something like you suggested, ie, remove the to-be-mutated element and readd it.所以最好按照你的建议做一些事情,即删除要变异的元素并阅读它。 And if there was a function that did what you wanted, it'd probably do something similar behind the scenes, because I can't think of a better way than bisect to place an element whose sorting order may have changed.如果有一个函数可以满足您的要求,它可能会在幕后做类似的事情,因为我想不出比 bisect 更好的方法来放置排序顺序可能已更改的元素。

def mutate_element(sortedlist, index, value):
    temp = sortedlist.pop(index)
    temp.append(value)
    sortedlist.add(temp)

You could also further generalise the functionality for various list-mutating methods.您还可以进一步概括各种列表变异方法的功能。 For example getattr(mylist, 'append') is the same as mylist.append .例如getattr(mylist, 'append')mylist.append相同。

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

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