Python 中 sorted 函数的详解

发布时间 2023-04-09 10:49:28作者: 夏夜星空晚风

1. 语法

sorted(iterable, cmp=None, key=None, reverse=False)

功能说明:

  • sorted() 函数是 Python 中的内置函数,sorted() 可以对所有可迭代的对象进行排序操作。
  • 内置的 sorted() 确保是稳定的。如果一个排序确保不会改变比较结果相等的元素的相对顺序就称其为稳定的 --- 这有利于进行多重排序(例如先按部门、再按薪级排序)。

参数说明:

  • iterable
    指定的可迭代对象;(例如:列表、元组、字典、集合、字符串等)
  • cmp
    比较函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回 1,小于则返回 -1,等于则返回 0。
  • key
    自定义排序规则;key 指定的函数将作用于 list 的每一个元素上,并根据 key 函数返回的结果进行排序。
  • reverse
    排序规则,reverse = True 降序, reverse = False 升序(默认)。

返回值说明:

  • 它将返回一个新的 list,不会改变原来的可迭代对象。

2. 常规示例

# 1. 对列表中的数字进行排序
a = [16, 5, -12, 11, -21]
print(sorted(a))
# 结果:[-21, -12, 5, 11, 16]


# 2. 对列表中的数字进行排序,并使用 key 接收一个自定义的排序
a = [16, 5, -12, 11, -21]
print(sorted(a, key=abs))
# 结果:[5, 11, -12, 16, -21]


# 3. 对字典进行排序,直接排序,默认使用第一个元素
d = { 'm': 5, 'n': 3, 'b': 4, 'v': 2, 'c': 1 }
print(sorted(d.items()))
# 结果:[('b', 4), ('c', 1), ('m', 5), ('n', 3), ('v', 2)]


# 4. 对字典进行排序,使用 key 的情况,指定第二个元素
d = { 'm': 5, 'n': 3, 'b': 4, 'v': 2, 'c': 1 }
print(sorted(d.items(), key=lambda x: x[1]))
# 结果:[('c', 1), ('v', 2), ('n', 3), ('b', 4), ('m', 5)]


# 5. 对字符串进行排序(默认情况下,对字符串排序,是按照 ASCII 的大小比较的)
a = 'aBcDeFgH'
print(sorted(a))
# 结果:['B', 'D', 'F', 'H', 'a', 'c', 'e', 'g']


# 6. 对字符串进行排序,使用 key 接收一个自定义的排序(忽略大小写,按照字母序排序)
a = 'aBcDeFgH'
print(sorted(a, key=str.lower))
# 结果:['a', 'B', 'c', 'D', 'e', 'F', 'g', 'H']


# 7. 对字符串进行排序,传入第三个参数 reverse=True,降序排列
a = 'aBcDeFgH'
print(sorted(a, key=str.lower, reverse=True))
# 结果:['H', 'g', 'F', 'e', 'D', 'c', 'B', 'a']

3. 特别示例

# 1. 按照元素出现的次数来排序
a = [8, 8, 6, 6, 6, 4, 2, 3]
print(sorted(a, key=lambda x: a.count(x)))
# 结果:[4, 2, 3, 8, 8, 6, 6, 6]


# 2. 一道面试题:多重排序(先按正数还是负数,分好正数组和负数组、再按照组内的绝对值排序)
#     条件1:正数在前负数在后
#     条件2:正数从小到大
#     条件3:负数从大到小

# 解法一:
a = [7, -8, 60, 4, 0, -20, -5]
print( sorted(a, key=lambda x: (x < 0, abs(x))) )
# 结果:[0, 4, 7, 60, -5, -8, -20]

# 解法二(等同于解法一):
a = [7, -8, 60, 4, 0, -20, -5]

def fn(x):
    # 默认情况下,reverse = False 升序
    # 然后我们的第一优先顺序为 True 或 False, (注意:False < True),所以正数在前面
    if x < 0:
        return True, abs(x)
    else:
        return False, abs(x)

print( sorted(a, key=fn) )