Python 中使用 cmp 的 sort()

问题描述 投票:0回答:3

我正在尝试对列表进行排序,将所有 0 移至列表末尾。 例如:[0,1,0,2,3,0,4]->[1,2,3,4,0,0,0]

我看到有人用 1 行代码

list.sort(cmp=lambda a,b:-1 if b==0 else 0)

但是我不明白括号里面的意思。

有人可以告诉我吗? 谢谢你。

sorting lambda python-2.x cmp
3个回答
17
投票

前言:

按照正常比较对列表进行排序

some_list.sort()   

提供自定义比较器

some_list.sort(cmp=my_comparator)

一个 lambda 函数

x = lambda a, b: a - b
# is roughly the same as
def x(a, b):
    return a - b

一个 if-else-表达式:

value = truthy_case if condition else otherwise
# is roughly the same as
if condition:
    value = truthy_case
else:
    value = otherwise

线路
list.sort(cmp=lambda a,b:-1 if b==0 else 0)
本身:

现在比较器中的条件是是否

b==0
,如果是则表明
b
a
的值大(结果的符号为负),否则表明比较的值相同(符号为零)。

虽然 Python 的

list.sort()
稳定,但这段代码并不理智,因为比较器也需要测试
a
,而不仅仅是
b
。正确的实现将使用
key
参数:

some_list.sort(key=lambda a: 0 if a == 0 else -1)

修复
list.sort(cmp=...)
实施:

如果你想使用

list.sort(cmp=...)
(你不想)或者你只是好奇,这是一个合理的实现:

some_list.sort(cmp=lambda a, b: 0 if a == b else
                               +1 if a == 0 else
                               -1 if b == 0 else 0)

但是请注意

在 Py3.0 中,

cmp
参数被完全删除(作为简化和统一语言的更大努力的一部分,消除了丰富的比较和
__cmp__
方法之间的冲突)。

替代方案:

对列表进行排序在

O(𝘯 log 𝘯)
中。我不知道对于这个简单的问题,代码是否运行得更快,但我不这么认为。
O(𝘯)
解决方案正在过滤:

new_list = [x for x in some_list if x != 0]
new_list.extend([0] * (len(some_list) - len(new_list)))

不过,这种差异可能只对很长的列表很重要。


0
投票
>>> sorted(l, key=lambda x:str(x) if x == 0 else x)
[1, 3, 4, 8, 0, 0, 0]

猜猜这里发生了什么?我正在利用这样一个事实:作为偏好,Python 将首先获取整数,然后获取字符串。所以我将 0 转换为 '0'。

这是证据。

>>> ll = [3,2,3, '1', '3', '0']
>>> sorted(ll)
[2, 3, 3, '0', '1', '3']

-1
投票

你应该自己回答,这是学习行动的计划:


三元表达式描述可以在这里找到:

https://docs.python.org/3/reference/expressions.html?highlight=ternary%20operator#conditional-expressions

你可以在该文档中找到很多表达式描述:

https://docs.python.org/3/reference/expressions.html


问:lambda是什么意思?

请花 5 天时间阅读有关 Python 语言的教程,这是原版 Gvinno Van Rossum 书的分支。

https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions

© www.soinside.com 2019 - 2024. All rights reserved.