我已经定义了一个列表如下:
list = [1,3,2,[4,5,6]]
Run Code Online (Sandbox Code Playgroud)
然后定义了一个比较方法如下:
def reverseCom(x,y):
if(x>y):
return -1
elif(x<y):
return 1
else:
return 0
Run Code Online (Sandbox Code Playgroud)
现在我使用reverseCom对列表进行了排序:
list.sort(reverseCom)
print list
Run Code Online (Sandbox Code Playgroud)
结果:[[4,5,6],3,2,1]
虽然元素[4,5,6]与列表中的其他元素不具有可比性.怎么不抛出任何错误?
你能帮助我理解python中用户定义的比较器的排序是如何工作的吗?
zay*_*ora 10
这是一个Python 2的怪癖.在Python 2中,数值和非数值是可比较的,并且数值始终被认为小于容器对象的值:
>>> 1 < [1]
True
>>> 1 < [2]
True
>>> 1558 < [1]
True
>>> 1 < {}
True
Run Code Online (Sandbox Code Playgroud)
另一方面,当比较不同类型的两个容器值时,考虑到它们的类型名称:
>>> () < []
False
>>> 'tuple' < 'list'
False
>>> {} < []
True
>>> 'dict' < 'list'
True
Run Code Online (Sandbox Code Playgroud)
但是,此功能已在Python 3中删除,这使得数字和非数字值不再具有可比性:
>>> 1 < [1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < list()
Run Code Online (Sandbox Code Playgroud)
编辑:下一个解释是完全基于实验,我找不到合理的文档备份.如果有人找到它,我很乐意通读它.
在比较用户定义的对象/非容器对象时,似乎Python 2有更多的规则.
在这种情况下,似乎数值始终大于非数字非容器值.
>>> class A: pass
...
>>> a = A()
>>> 1 > a
True
>>> 2.7 > a
True
Run Code Online (Sandbox Code Playgroud)
现在,在比较不同的非数字,非容器类型的两个对象时,似乎是它们的地址被考虑在内:
>>> class A: pass
...
>>> class B: pass
...
>>> a = A()
>>> a
<__main__.A instance at 0x0000000002265348>
>>> b = B()
>>> b
<__main__.B instance at 0x0000000002265048>
>>> a < b
False
>>> b < a
True
Run Code Online (Sandbox Code Playgroud)
如果你问我,这真的是香蕉.
当然,如果你想覆盖类定义中的__lt__()和__gt__()方法,那么所有这些都可以改变,这决定了<和>运算符的标准行为.
有关这些方法如何运作的进一步文档可以在这里找到.
底线:尽可能避免不同类型之间的比较.结果实际上是不可预测的,不直观的,并没有充分记录.此外,尽可能使用Python 3.
您的比较器实际上可以工作,即不会抛出任何错误:
In [9]: reverseCom([4,5,6],1)
Out[9]: -1
In [10]: reverseCom([4,5,6],2)
Out[10]: -1
In [11]: reverseCom([4,5,6],3)
Out[11]: -1
Run Code Online (Sandbox Code Playgroud)
它起作用的原因是,list实例总是比int实例大:
In [12]: [1,2,3] > 5
Out[12]: True
In [13]: ['hello'] > 5
Out[13]: True
In [14]: [] > -1
Out[14]: True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
213 次 |
| 最近记录: |