[英]Sorting class instances in python
python 2.7用于排序vanilla类实例的是什么? 我对默认排序行为感兴趣。
假设我有班级
class S():
pass
然后我可以创建几个实例,并对它们进行排序:
a = S(); b = S(); c = S()
l = [(a,'a'), (b,'b') ,(c, 'c')]
sorted(l)
这将打印一些对象的排序。 现在我有两个问题:
__hash__()
,因此他们的id()
? __hash__()
来影响排序行为? Python 3的内置排序使用了类中的__lt__
方法。
丰富的比较方法在Python中很特殊,因为如果没有定义__lt__
,它们可以返回一个特殊的NotImplemented
类型 - 看看这个页面上的文档: http : __lt__
该标准型的层次结构
由于NotImplemented
的真值是True
,任何得到NotImplemented
布尔比较都将继续,就好像第一个元素实际上小于第二个元素一样,这将导致排序按照与原来相同的顺序离开列表。
看一下交互式shell。 您可以看到如何在排序中使用真值,并且Python认为两个对象都小于彼此:
>>> class S():
... pass
...
>>> a = S()
>>> b = S()
>>> a.__lt__( b )
NotImplemented
>>> if a.__lt__( b ):
... print( "derp!" )
...
derp
>>> if b.__lt__(a):
... print( "derp" )
...
derp
以下是一些参考资料:
编辑:看了Python 2.7之后,它看起来像对象的ID用于排序,并且__lt__
方法在像你的例子这样的简单类上是未定义的。 对不起任何困惑。
Python的排序算法使用“小于”测试专门比较项目,这可以使用类上的__cmp__()
特殊方法(现已弃用)或__lt__()
来实现。
在没有关于如何比较两个对象的任何特定指令的情况下,对于相同类型的对象,使用id()
(而不是哈希),就像在您的情况下一样。
我在自己的机器上尝试了你的例子(python 2.7):
>>> sorted(l)
[(<__main__.S instance at 0x107142a70>, 'a'), (<__main__.S instance at 0x107142ab8>, 'b'), (<__main__.S instance at 0x107142b00>, 'c')]
请注意,排序列表按id()
顺序排列:
>>> id(a)
4413729392
>>> id(b)
4413729464
>>> id(c)
4413729536
如果我生成哈希,我得到:
>>> hash(a)
275858087
>>> hash(b)
-9223372036578917717
>>> hash(c)
275858096
这表明排序不是基于哈希。
有关如何使python按照您的方式对您的类进行排序的信息,请参阅derekerdmann的答案。
编辑:顺便说一句,如果您将项目反向放入列表然后对其进行排序,您会得到:
>>> l = [(c,'c'), (b, 'b'), (a, 'a')]
>>> sorted(l)
[(<__main__.S instance at 0x107142a70>, 'a'), (<__main__.S instance at 0x107142ab8>, 'b'), (<__main__.S instance at 0x107142b00>, 'c')]
再一次,它按id()
顺序排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.