复杂的 lambda 表达式作为排序函数的关键参数

And*_*huk 0 python sorting

我有一个示例代码:

In [60]: sorted([3, 1, None], key=lambda x: (x is None, x))
Out[60]: [1, 3, None]

In [61]: sorted([3, 1, None], key=lambda x: (x is not None, x))
Out[61]: [None, 1, 3]

Run Code Online (Sandbox Code Playgroud)

我想我确实理解它的作用 - 看起来它允许None在排序过程中跳过键的值,否则排序会引发尝试TypeError比较- 但我不明白它是如何以及为什么如此工作的。具体来说,我对返回元组的 lambda 函数感到困惑。intNone

我在排序HOWTO中找不到任何相关内容。我希望得到解释或记录此行为的链接。

Ste*_*tef 5

元组按字典顺序进行比较和排序:

>>> sorted([(0, 17), (1,15), (0,12), (0, 9), (1, 8), (1, 7), (0, 2)])
[(0, 2), (0, 9), (0, 12), (0, 17), (1, 7), (1, 8), (1, 15)]
>>> (0, 12) < (1, 9)
True
>>> (0, 12) < (0, 13)
True
>>> (1, 12) < (0, 9)
False
Run Code Online (Sandbox Code Playgroud)

“词典顺序”只是“就像英语词典中的单词”的一个花哨词:首先比较第一个字母,并且仅当第一个字母相等时,然后比较第二个字母,并且仅当前两个字母相等时,然后比较第三个字母,依此类推。

使用元组作为键,元组也会按字典顺序进行比较。

在您的情况下,x is Nonex is not None评估为布尔值,TrueFalse.

布尔值也可以进行比较:

>>> False < True
True
>>> True < False
False
Run Code Online (Sandbox Code Playgroud)

因此,sorted([3, 1, None], key=lambda x: (x is None, x))将认为最小的元素是那些为x is NoneFalse 的元素,最大的元素是那些为x is NoneTrue 的元素:

>>> sorted([3, 1, None], key=lambda x: (x is None, x))
[1, 3, None]
>>> sorted(map(lambda x: (x is None, x), [3, 1, None]))
[(False, 1), (False, 3), (True, None)]
Run Code Online (Sandbox Code Playgroud)