Python的sort自定义compare函数

记住这个规律:

1.无论是什么,都先左侧的大, if x > y :固定写法。

2.大的放右边就return 1 ;如果想要大的放左边就return -1;

  • 这里记忆是【-1,1】坐标轴上,-1在左侧,1在右侧

 

# 默认sort是左小-右大,的return 1
# 要排序大的,就右侧大的return 1
def compare(x, y):
    if x > y:
        return 1    # 右边
    elif x < y:
        return -1
    else:
        return 0


def max_number(nums):
    nums = [str(num) for num in nums]
    nums.sort(key=cmp_to_key(compare))
    # nums.sort() 
    return ''.join(nums)


# test case 1
print(max_number(['1', '2','3','4'],))  # 22221

放右边的效果:

 

===========

现在大的想放左边:

 

cmp_to_key的说明:

问1:```from functools import cmp_to_key```请问python里面的这个是什么?

`cmp_to_key` 函数是 Python `functools` 模块中的一个工具,用于将一个老式的比较函数(即 cmp 函数)转换为一个可用于 `sorted`、`min`、`max` 等函数的键函数(key function)。这很有用,特别是在迁移旧代码或使用需要比较两个元素并返回它们大小关系的函数时。

在 Python 2 中,`sorted` 和其他排序方法既支持 key 函数(就是接受单个参数,并返回用于排序的值)也支持 cmp 函数(接受两个参数,比较它们并返回负数、零或正数表示它们的大小关系)。

但是,在 Python 3 中,cmp 函数支持被移除了,取而代之的是仅支持 key 函数的方法。这时 `cmp_to_key` 函数就变得很有用,它帮助转换 cmp 函数到一个适用于 Python 3 排序方法的 key 函数。

举个例子:

```python
from functools import cmp_to_key

# 假设我们有一个比较函数,用于比较两个数字的字符串表示法
def numeric_compare(x, y):
    if int(x) < int(y):
        return -1
    elif int(x) > int(y):
        return 1
    else:
        return 0

# 我们可以使用 cmp_to_key 将其转换为键函数
key_func = cmp_to_key(numeric_compare)

# 然后我们可以在排序中使用这个键函数
sorted_strings = sorted(['5', '3', '2', '8', '7'], key=key_func)
print(sorted_strings) # 输出应该是 ['2', '3', '5', '7', '8']
```

在上面的例子中,我们使用 `cmp_to_key` 来转换一个比较两个字符串数字并返回它们大小关系的 `numeric_compare` 函数。之后,我们就可以将生成的 key 函数(`key_func`)传递给 `sorted` 函数以确保元素按照其数值大小排序。

问:cmp_to_key 为什么可以把自定义的函数转化为键函数?这里的键函数是什么?有什么特殊的吗?

`cmp_to_key` 函数能够把旧式的比较函数转换为键函数,是因为它内部实现了一个特殊的包装类,这个类使用比较函数来定义对象间的比较操作。这样,当排序算法需要比较两个对象时,它实际上是调用这个类的特殊方法来进行比较。

键函数(key function)是一个接受单个输入参数并返回一个用于排序的值的函数。排序算法使用这个返回值来决定元素间的排序顺序,而不是直接比较元素本身。键函数应该对每个元素返回一个可以被 `<` 操作符直接比较的值。

内部实现的大概原理是这样的:

1. `cmp_to_key` 接收一个比较函数 `my_cmp` 作为参数,并返回一个转换函数 `key_wrapper`。
2. 当元素需要使用键函数进行排序时,`key_wrapper` 会被调用,并且为每个元素生成一个 `K` 类的实例,其中 K 类封装了该元素和原始的比较函数 `my_cmp`。
3. 这个 `K` 类重载了 `__lt__`(小于)、`__gt__`(大于)、`__eq__`(等于)等专用方法,以便在需要进行比较的时候,没有直接的比较方法可用时,使用封装的 `my_cmp` 函数来确定大小。
4. 当排序算法尝试比较两个 `K` 实例时,它会使用这些方法,从而实际上使用了 `my_cmp` 函数进行比较。

使用 `cmp_to_key` 包装后,排序算法就可以像使用简单键函数那样使用您的比较函数来排序。这个过程对于排序算法来说是透明的,排序算法只知道它需要根据 `<`、`==` 等操作符比较键值,而具体键值背后的比较逻辑则隐藏在 `cmp_to_key` 的内部实现中。

下面是一个具体的使用例子:

```python
from functools import cmp_to_key

# 自定义比较函数
def compare_items(a, b):
    if a < b:
        return -1
    elif a > b:
        return 1
    else:
        return 0

# 使用 cmp_to_key 包装比较函数
key_func = cmp_to_key(compare_items)

# 使用键函数进行排序
items = [5, 2, 4, 1, 3]
sorted_items = sorted(items, key=key_func)
print(sorted_items)
```

在这个例子中,`sorted_items` 将是按照 `compare_items` 函数的逻辑排序的列表。通过 `cmp_to_key` 的包装,原本的 `compare_items` 函数就能够被排序算法用作键函数。

总结:

  • 记住把,大佬们已经帮我们封装好了这个。
  • python2有sort有比较函数的参数,python3去掉了,但是这个方法挺好用的,所以我们用from functools import cmp_to_key导入继续使用。(我的理解)
  • AI 帮助我学习成长~~~!!哈哈

参考:

菜鸟教程:https://www.runoob.com/python/att-list-sort.html

gpt-4-0613

以及我自己

posted @ 2024-01-23 13:20  o蹲蹲o  阅读(237)  评论(0编辑  收藏  举报