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

SortedList does not find an element it contains while list does

在一个项目中,我正在使用 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 and sorted_list is a SortedContainers.SortedList 的 class。有没有人知道为什么纯列表和排序列表之间会有区别?

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 的项目具有相同的价值(即它们的排序是任意的)。这打破了二分逻辑。有人知道如何解决这个问题吗?

一样,问题在于 SortedList 依赖于二分法,因此要求所有元素在排序时绝对严格(即,如果 __eq__ 在对象之间 False,他们的 __lt__ 也需要不同且统一)。我通过跟踪我创建了多少个对象并在我实际感兴趣的值相等时使用创建索引来解决这个问题。这是一种相当随意的方法,可以换成任何其他严格的排序。