如何在Python列表中移除一个对象

6
我创建了一个名为point的类,如下所示:
class point:
    def __init__(self):
        self.x = 0
        self.y = 0

并创建一个 point 实例列表:

p1 = point()
p1.x = 1
p1.y = 1
p2 = point()
p2.x = 2
p2.y = 2
p_list = []
p_list.append(p1)
p_list.append(p2)

现在我想从列表中删除 x = 1y = 1 的实例,我该怎么做?

我尝试为类 point 添加一个 __cmp__ 方法,如下所示:

class point:
    def __init__(self):
        self.x = 0
        self.y = 0    
    def __cmp__(self, p):
        return self.x==p.x and self.y==p.y

但是以下代码无法正常工作。
r = point()
r.x = 1
r.y = 1
if r in p_list:
    print('correct')
else:
    print('wrong') # it will go here
p_list.remove(r) # it reports 'ValueError: list.remove(x): x not in list'

1
我认为这与r与您尝试删除的列表中的项目不是_完全相同_有关。 - Aaron Christiansen
1
我认为@OrangeFlash81是正确的。尽管p1和r在x和y方面具有相同的“值”,但它们并不是“相同的对象”。 - John Gordon
1
你的__cmp__定义看起来不对。它应该返回一个整数,而不是布尔值。 - Kevin
是的,它们不是同一个对象,但我希望列表将它们视为相同的对象,因为它们具有相同的x和y值。 - Deng Haijun
@Kevin 我已将 cmp 方法更改为以下内容,但在 Python 3.5 上仍无法运行。def __cmp__(self, p): if self.x==p.x: return self.y-p.y else: return self.x-p.x - Deng Haijun
有一个我错过的事实:Python 3 不再支持 __cmp__。 - Deng Haijun
2个回答

8
你的__cmp__函数不正确。__cmp__应该返回-1/0/+1,这取决于第二个元素是小于/等于/大于self。因此当调用__cmp__时,如果元素相等,则返回True,这将被解释为1,因此是“大于”。如果元素不相等,则返回False,即0,这被解释为“等于”。
对于二维点而言,“大于”和“小于”的定义并不十分清晰,因此您可以将__cmp__替换为__eq__,并使用相同的实现。您的point类应如下所示:
class point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y    

    def __eq__(self, p):
        return self.x==p.x and self.y==p.y

2
两点需要注意:首先,如果您没有定义__ne__,那么!=仍将使用身份比较。其次,通常建议像__eq__这样的特殊方法在另一个操作数不是该方法设计用于处理的类型时返回NotImplemented - user2357112

0

当您检查r是否在p_list中时,您会创建一个新的point实例,因此该point实例不会在列表中(它在内存中具有不同的位置)。

此函数可用于删除x和y均为1的点:

for idx, p in enumerate(p_list):
    if p.x==1 and p.y==1:
        del p_list[idx]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接