<p>根据<code>cmp_to_key</code>(<a href="https://docs.python.org/2/library/functools.html#functools.cmp_to_key" rel="nofollow noreferrer">https://docs.python.org/2/library/functools.html#functools.cmp_to_key</a>)的文档,您的比较函数是错误的:</p>
<blockquote>
<p>A comparison function is any callable that accept two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than.</p>
</blockquote>
<p>您的<code>comparator</code>函数返回布尔值True或False,您可以通过以下方式将其重写为所需的规范:</p>
<pre><code>def comparator(a, b):
lhs = (-a.score, a.name) # negating score to sort descending
rhs = (-b.score, b.name)
if lhs == rhs:
return 0
elif lhs < rhs:
return -1
else:
return 1
</code></pre>
<p><strong>更新:</strong>
正如@ShadowRanger指出的,比较函数可以更有效地编写为:</p>
<pre><code>def comparator(a, b):
lhs = (-a.score, a.name) # negating score to sort descending
rhs = (-b.score, b.name)
return lhs > rhs or -(lhs < rhs)
</code></pre>
<p>为了理解为什么/如何工作,您需要知道在Python中<code>bool</code>是<code>int</code>的子类(和子类型),并且<code>False</code>被定义为<code>0</code>,<code>True</code>被定义为<code>1</code>(来自PEP-0285):</p>
<pre><code>False = int.__new__(bool, 0)
True = int.__new__(bool, 1)
</code></pre>
<p>这意味着你可以做一些“奇怪”的事情,比如:</p>
<pre><code>>>> True + 1
2
>>> -True
-1
>>> -False
0
</code></pre>
<p>所以如果<code>lhs > rhs</code>(我们应该返回<code>1</code>),那么标记的部分</p>
<pre><code>return lhs > rhs or -(lhs < rhs)
^^^^^^^^^
</code></pre>
<p>是<code>True</code>(<code>1</code>),并且<code>or</code>的右边不会被执行,我们根据需要返回<code>1</code>。你知道吗</p>
<p>如果<code>lhs < rhs</code>(我们应该返回<code>-1</code>),那么上面标记的部分将是<code>False</code>,因为<code>False or x == x</code>我们剩下:</p>
<pre><code>return -(lhs < rhs)
^^^^^^^^^
</code></pre>
<p>其中标记的部分是<code>True</code>:</p>
<pre><code>return -(True)
</code></pre>
<p>从上面看<code>-True</code>是<code>-1</code>,这就是我们想要返回的这个例子。你知道吗</p>
<p>如果<code>lhs == rhs</code>(我们应该返回<code>0</code>),我们得到</p>
<pre><code>return False or -(False)
</code></pre>
<p><code>False or x</code>仍然是<code>x</code>,因此剩下:</p>
<pre><code>return -(False)
</code></pre>
<p>从上面看,是<code>0</code>。你知道吗</p>
<p><strong>注意:</strong>在Python中看到这些类型的函数已经不常见了,现在您通常在类中定义<code>__lt__</code>和<code>__eq__</code>,并使用<code>total_ordering</code>中的<code>functools</code>(<a href="https://docs.python.org/3.3/library/functools.html#functools.total_ordering" rel="nofollow noreferrer">https://docs.python.org/3.3/library/functools.html#functools.total_ordering</a>)修饰符。你知道吗</p>