Python编程:列表List.sort和sorted方法排序

简介: Python编程:列表List.sort和sorted方法排序

排序方法

2.x的代码移植到3.x时,需要将cmp函数转化为key函数


# Python2
list.sort(cmp=None, key=None, reverse=False)
# Python3
list.sort(key=None, reverse=False)

排序有两个方法


list.sort()   # list本身将被修改, 返回None
sorted()      # 不修改原来的list, 返回一个新的list

排序示例

1、list.sort示例


lst = [3, 2, 1]
print(lst)  # [3, 2, 1]
ret = lst.sort()
print(ret)  # None
print(lst)  # [1, 2, 3]

2、sorted示例


lst = [3, 2, 1]
print(lst)  # [3, 2, 1]
ret = sorted(lst)
print(ret)  # [1, 2, 3]
print(lst)  # [3, 2, 1]

看一个实际需求

有一个人员列表,需要按给定需求排序


from pprint import pprint
# name:姓名
# money:钱
# age:年龄
lst = [
    {
        'name': 'Tom',
        'age': 20,
        'money': 2000
    },
    {
        'name': 'Jack',
        'age': 25,
        'money': 2000
    },
    {
        'name': 'Alice',
        'age': 25,
        'money': 3000
    },
    {
        'name': 'Steve',
        'age': 25,
        'money': 3000
    }
]
# 未排序前
pprint(lst)
"""
[{'age': 20, 'money': 2000, 'name': 'Tom'},
 {'age': 25, 'money': 2000, 'name': 'Jack'},
 {'age': 25, 'money': 3000, 'name': 'Alice'},
 {'age': 25, 'money': 3000, 'name': 'Steve'}]
"""

1、需求一:单字段排序,钱多的在前


(1)使用lambda 表达式


# 默认从小到大,reverse=True可以逆序排列
lst.sort(key=lambda item: item['money'], reverse=True)
pprint(lst)
"""
[{'age': 25, 'money': 3000, 'name': 'Alice'},
 {'age': 25, 'money': 3000, 'name': 'Steve'},
 {'age': 20, 'money': 2000, 'name': 'Tom'},
 {'age': 25, 'money': 2000, 'name': 'Jack'}]
"""

(2)使用operator.itemgetter 替换 lambda 表达式


from operator import itemgetter
lst.sort(key=itemgetter('money'), reverse=True)
pprint(lst)
"""
[{'age': 25, 'money': 3000, 'name': 'Alice'},
 {'age': 25, 'money': 3000, 'name': 'Steve'},
 {'age': 20, 'money': 2000, 'name': 'Tom'},
 {'age': 25, 'money': 2000, 'name': 'Jack'}]
"""

(3)使用sorted

from operator import itemgetter
lst2 = sorted(lst, key=itemgetter('money'), reverse=True)
pprint(lst2)
"""
[{'age': 25, 'money': 3000, 'name': 'Alice'},
 {'age': 25, 'money': 3000, 'name': 'Steve'},
 {'age': 20, 'money': 2000, 'name': 'Tom'},
 {'age': 25, 'money': 2000, 'name': 'Jack'}]
"""

以上三种方式排序结果都一样


2、需求二:多字段排序


需要满足3个排序要求


钱money 多的在前面

如果钱money 一样多,年龄age 大的在前

如果钱money 和年龄age 都一样,按照名字首字母顺序排序Z-A排序

如果有一个排序函数就很容易解决


(1) 方式一: 自定义一个排序函数


from functools import cmp_to_key
# 自定义一个排序函数
def foo(a, b):
    if a['money'] > b['money']:
        return 1
    elif a['money'] < b['money']:
        return -1
    else:
        if a['age'] > b['age']:
            return 1
        elif a['age'] < b['age']:
            return -1
        else:
            return ord(a['name'][0]) - ord(b['name'][0])
# Python3中需要用到cmp_to_key 函数
lst.sort(key=cmp_to_key(foo), reverse=True)
pprint(lst)
"""
[{'age': 25, 'money': 3000, 'name': 'Steve'},
 {'age': 25, 'money': 3000, 'name': 'Alice'},
 {'age': 25, 'money': 2000, 'name': 'Jack'},
 {'age': 20, 'money': 2000, 'name': 'Tom'}]
"""

(2)方式二:自定义一个class类,在类中重写排序方法



from functools import total_ordering
# 通过__eq__ 和其他(__ne__, __lt__, __gt__)任意一个方法就可以推导出来其他方法
@total_ordering
class Person(object):
    def __init__(self, name, age, money):
        self.name = name
        self.age = age
        self.money = money
    def __eq__(self, other):
        return self.money == other.money and \
               self.age == other.age and \
               ord(self.name[0]) - ord(other.name[0])
    def __lt__(self, other):
        return self.money < other.money or \
               self.age < other.age or \
               ord(self.name[0]) - ord(other.name[0])
    def __str__(self):
        return f"{{age: {self.age}, money: {self.money}, name: {self.name}}}"
    __repr__ = __str__
persons = [Person(**item) for item in lst]
new_persons = sorted(persons, reverse=True)
pprint(new_persons)
"""
[{age: 25, money: 3000, name: Steve},
 {age: 25, money: 3000, name: Alice},
 {age: 25, money: 2000, name: Jack},
 {age: 20, money: 2000, name: Tom}]
"""

(3)方式三:使用多个key进行排序


from operator import itemgetter
lst.sort(key=itemgetter('money', 'age', 'name'), reverse=True)
pprint(lst)
"""
[{'age': 25, 'money': 3000, 'name': 'Steve'},
 {'age': 25, 'money': 3000, 'name': 'Alice'},
 {'age': 25, 'money': 2000, 'name': 'Jack'},
 {'age': 20, 'money': 2000, 'name': 'Tom'}]
"""

以上3种方式实现了多个字段排序


参考

python 列表排序方法sort、sorted技巧篇

https://www.runoob.com/python/att-list-sort.html

https://www.runoob.com/python3/python3-att-list-sort.html

相关文章
|
2月前
|
Python
Python编程:运算符详解
本文全面详解Python各类运算符,涵盖算术、比较、逻辑、赋值、位、身份、成员运算符及优先级规则,结合实例代码与运行结果,助你深入掌握Python运算符的使用方法与应用场景。
211 3
|
2月前
|
数据处理 Python
Python编程:类型转换与输入输出
本教程介绍Python中输入输出与类型转换的基础知识,涵盖input()和print()的使用,int()、float()等类型转换方法,并通过综合示例演示数据处理、错误处理及格式化输出,助你掌握核心编程技能。
479 3
|
2月前
|
并行计算 安全 计算机视觉
Python多进程编程:用multiprocessing突破GIL限制
Python中GIL限制多线程性能,尤其在CPU密集型任务中。`multiprocessing`模块通过创建独立进程,绕过GIL,实现真正的并行计算。它支持进程池、队列、管道、共享内存和同步机制,适用于科学计算、图像处理等场景。相比多线程,多进程更适合利用多核优势,虽有较高内存开销,但能显著提升性能。合理使用进程池与通信机制,可最大化效率。
295 3
|
2月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
302 0
|
9月前
|
存储 人工智能 索引
Python数据结构:列表、元组、字典、集合
Python 中的列表、元组、字典和集合是常用数据结构。列表(List)是有序可变集合,支持增删改查操作;元组(Tuple)与列表类似但不可变,适合存储固定数据;字典(Dictionary)以键值对形式存储,无序可变,便于快速查找和修改;集合(Set)为无序不重复集合,支持高效集合运算如并集、交集等。根据需求选择合适的数据结构,可提升代码效率与可读性。
|
10月前
|
安全 数据处理 索引
深入探讨 Python 列表与元组:操作技巧、性能特性与适用场景
Python 列表和元组是两种强大且常用的数据结构,各自具有独特的特性和适用场景。通过对它们的深入理解和熟练应用,可以显著提高编程效率和代码质量。无论是在数据处理、函数参数传递还是多线程环境中,合理选择和使用列表与元组都能够使得代码更加简洁、高效和安全。
285 9
|
存储 索引 Python
Python学习笔记----列表、元组和字典的基础操作
这篇文章是一份Python学习笔记,涵盖了列表、元组和字典的基础操作,包括它们的创建、修改、删除、内置函数和方法等。
Python学习笔记----列表、元组和字典的基础操作
|
存储 索引 Python
五:《Python基础语法汇总》— 列表&元组&集合
本篇文章讲解了关于列表;元组和集合这三个基本数据类型的常用方法与函数。及同一性操作符;成员判断符;浅拷贝与深拷贝等多方面的知识点
146 4
|
Python
Python多维列表(元组)合并成一维形式
Python多维列表(元组)合并成一维形式
189 2
|
存储 Python
Python 中的列表和元组
【8月更文挑战第29天】
358 1

推荐镜像

更多