SortedList找不到它包含的元素,而list找到了



在一个项目中,我使用的是SortedContainers.SortedList。在以下伪代码中,我得到了一个断言错误:

assert custom_class in list(sorted_list) # This does not cause an error
assert custom_class in sorted_list # This causes an assertion error

不幸的是,我还无法创建一个可运行的小示例来重现错误。custom_class是从abc.ABC派生的类,而sorted_listSortedContainers.SortedList。有人知道为什么纯列表和SortedList之间会有区别吗?

sorted_list.remove()也抛出错误,因为SortedList.bisect_left()也找不到元素。。。

谢谢!

第1版:问题似乎发生在SortedList:的__contains__

def __contains__(self, value):
"""Return true if `value` is an element of the sorted list.
``sl.__contains__(value)`` <==> ``value in sl``
Runtime complexity: `O(log(n))`
>>> sl = SortedList([1, 2, 3, 4, 5])
>>> 3 in sl
True
:param value: search for value in sorted list
:return: true if `value` in sorted list
"""
_maxes = self._maxes
if not _maxes:
return False
pos = bisect_left(_maxes, value)
if pos == len(_maxes):
return False
_lists = self._lists
idx = bisect_left(_lists[pos], value) # <- This finds the wrong index (in my case 38 instead of 39)
return _lists[pos][idx] == value # <- The comparison here consequently leads to a falsey value

第2版:问题是,位置38和39处的项目具有相等的值(即,它们的排序是任意的(。这打破了bisec的逻辑。有人知道如何解决这个问题吗?

正如jsonharper在评论中指出的那样,问题在于SortedList依赖于bisec,因此要求所有元素在排序时都是绝对刚性的(即,如果对象之间的__eq__False,则它们的__lt__也需要不同且统一(。我通过跟踪我创建了多少个对象来解决这个问题,如果我真正感兴趣的值相等,我会使用创建索引。这是一种非常随意的方法,可以与任何其他严格的排序进行交换。

最新更新