Python 使用丢弃时出现 SortedSet ValueError

Python SortedSet ValueError when using discard

我正在使用 SortedSet 按排序顺序存储对象。我一直收到 ValueError 对象不在列表中,即使该对象确实在列表中。

这是一个可重现的例子

from sortedcontainers import SortedSet

a = SortedSet()

class example:
    def __init__(self,p, id):
        self.p = p
        self.id = id
    def __lt__(self, other):
        return self.p < other.p
 


a.add(example(5, 1))
x = example(5, 2)
a.add(x)

if x in a:
    print("found")
    a.discard(x)

在这个例子中,“found”被打印出来,我得到 ValueError: <__main__.example object at 0x7fc19ebb2400> not in list

几个小时以来,我一直在努力弄清楚为什么会失败,非常感谢任何帮助。

编辑: 这是完整的回溯

Traceback (most recent call last):
  File "/CLD/clockwork-rl/work/Clockwork-RL/temp.py", line 18, in <module>
    a.discard(x)
  File "/home/salzayat/.local/lib/python3.7/site-packages/sortedcontainers/sortedset.py", line 422, in discard
    self._list.remove(value)
  File "/home/salzayat/.local/lib/python3.7/site-packages/sortedcontainers/sortedlist.py", line 462, in remove
    raise ValueError('{0!r} not in list'.format(value))
ValueError: <__main__.example object at 0x7f3783488400> not in list

编辑2:

我更新了代码以修复缺失的 return,但仍然产生错误。

我现在明白我还需要为 id 添加一个条件。我不确定为什么这是必要的,因为它可以检测到 x 在 orderedset 中并且 found 仍在打印

您忘记了 return self.p < other.p

你class的方法不一致。您还没有实现全套比较方法,或 __hash__ 方法。你只有 __lt__.

此外,您实施 __lt__ 的方式为 return self.p < other.p,这意味着就您的订单比较而言,example(5, 1)example(5, 2) 是相等的(与您继承的 __eq__ 的行为相反)。如果您希望能够在同一个 SortedSet 中存储两个具有相等 p 值的对象,您的比较运算符必须能够区分这两个对象。

由于您的方法不一致,它们向 SortedSet 实现报告了相互矛盾的信息。基于散列和 == 的实现部分认为您的对象不同,但基于 < 的实现部分认为您的对象是相等的,并且 SortedSet 变得非常混乱。