Python 列表 remove 方法:实现原理如何?
在Java中,我有一个客户端类,这个类有一个叫“code”的属性,还有一个equals方法。这个equals方法会接收另一个客户端对象,并把它的code属性和自己进行比较。
在Python中,我刚刚了解到有一个__cmp__
方法,可以实现和Java的equals方法一样的功能。于是,我也这样做了。我创建了一个客户端类,里面有“code”属性,还有一个comp方法,用来检查code是否相同。
class Client():
def __init__(self, code):
self.code = code
def __cmp__(self, obj):
return obj.code == self.code
def __repr__(self):
return str(self.code)
然后,我把3个Client对象放进了一个Python的列表里:
bla = [Client(1), Client(2), Client(3)]
接着,当我尝试:
bla.remove(Client(3))
结果很神奇,Python把第一个元素(code为1的Client)给删除了。
我到底做错了什么呢?我查找了Python库文件中列表的实现,但不太容易找到。
有没有人能帮帮我?
2 个回答
听起来你其实想要用 __eq__
这个东西。
class Client():
def __init__(self, code):
self.code = code
def __eq__(self, obj):
return obj.code == self.code
# this is how you usually write cmp, Amber explained the problem
def __cmp__(self, other):
return cmp(self.code, other.code)
def __repr__(self):
return str(self.code)
顺便说一下,你的那个有问题的例子里,__cmp__
返回了 False,这是符合预期的。但是在 Python 里,False == 0
,也就是说如果 __cmp__
返回 0,就表示比较的两个元素是相等的。所以这就是为什么它会把第一个元素去掉的原因!
http://docs.python.org/reference/datamodel.html#object.__cmp__
__cmp__(self, other)
当进行比较操作时,如果没有定义丰富的比较方法,就会调用这个方法。这个方法应该返回一个负数,如果
self
小于other
;返回零,如果self
等于other
;返回一个正数,如果self
大于other
。
基本上,你应该修改你的 __cmp__
方法实现为...
def __cmp__(self, obj):
return cmp(obj.code, self.code)
Python 中的 cmp()
内置函数专门设计用来比较两个参数,并返回 __cmp__
方法应该返回的值。
Python 还有一个不同的函数叫 __eq__
,它只检查两个对象是否相等,而你当前的 __cmp__
实现更适合这个功能。