是否有任何Python2的实现,其中排序是可传递的?

wim*_*wim 8 python sorting python-2.x transitivity strict-weak-ordering

是否存在Python2的现有实现,其中排序是可传递的?也就是说,如果不创建用户定义的类型,则无法看到此行为:

>>> x < y < z < x
True
Run Code Online (Sandbox Code Playgroud)

由于这种反例,CPython不具有传递性

x = 'b'
y = ()
z = u'ab'
Run Code Online (Sandbox Code Playgroud)

但是,CPython中的这种排序仅记录为实现细节.

Ble*_*der 4

除了 Skulpt 之外,每个主流 Python 实现都会以某种方式失败,但它可以说是一个不完整的实现。

CPython(及其变体)、PyPy 和 Jython

>>> 'b' < () < u'ab' < 'b'
True
Run Code Online (Sandbox Code Playgroud)

铁蟒

IronPython 在内部比较Object.GetHashCode()不同对象的 .NET 哈希值,因此您可以通过滥用 的特殊处理intfloat比较来破坏它,并且事实上 的内部哈希表示float('+inf')小于 的哈希值[](我不确定这有多稳定,因此它可能不适用于所有 IronPython 安装):

>>> 2**200 < float('+inf') < [] < 2**200
True
Run Code Online (Sandbox Code Playgroud)

CLPython

>>> {1: 3} < {1: 4} < {1: 3}
1
>>> {1: 3} < {1: 3}
0
Run Code Online (Sandbox Code Playgroud)

雕塑

如果你将Skulpt视为 Python 2 的完整实现(它无法比较字典和其他一些不方便的类型,并且没有unicode类型),它实际上通过复制 CPython 的比较规则并方便地省略类型来工作unicode

# 1. None is less than anything
# 2. Sequence types are greater than numeric types
# 3. [d]ict < [l]ist < [s]tring < [t]uple

>>> None < 0 < {} < [] < '' < ()
True
Run Code Online (Sandbox Code Playgroud)

对于 CPython 2,您实际上会有[t]uple < [u]nicode,但因为unicodestr比较是作为特殊情况处理的,所以您会失去传递性。尽管 Python 2 不太可能获得补丁来修复这个“bug”,但我认为您可以通过显式更改顺序来确保传递性:

[d]ict < [l]ist < [s]tring < [t]uple < [u]nicode
Run Code Online (Sandbox Code Playgroud)

到:

[u]nicode < [d]ict < [l]ist < [s]tring < [t]uple
Run Code Online (Sandbox Code Playgroud)

这样,比较的特殊情况strunicode不会破坏任何东西。