0

0

python怎么排序列表_python列表排序方法大全

下次还敢

下次还敢

发布时间:2025-08-26 15:27:01

|

1055人浏览过

|

来源于php中文网

原创

Python中排序列表最常用的方法是list.sort()和sorted()函数。list.sort()直接修改原列表,不返回新列表,适用于无需保留原始顺序的场景;sorted()则返回一个新的已排序列表,原列表保持不变,适合需要保留原始数据的情况。两者均支持reverse参数进行降序排序,并使用高效的Timsort算法。关键区别在于:list.sort()是原地操作,节省内存;sorted()无副作用,更安全灵活。对于复杂排序需求,可通过key参数传入函数实现自定义规则,如按对象属性、忽略大小写或多重条件排序。处理混合数据类型时,可设计key函数统一比较逻辑,确保不同类型元素能正确排序。掌握这两种方法及其适用场景,有助于编写高效且可维护的代码。

python怎么排序列表_python列表排序方法大全

Python中对列表进行排序,最直接且常用的方法就是利用其内置的

list.sort()
方法或者
sorted()
函数。它们都能帮你把杂乱无章的列表变得井然有序,只是在使用场景和效果上有些微妙的区别,理解这些差异是高效编程的关键。

解决方案

当我们需要对Python列表进行排序时,通常会用到两个核心工具

list.sort()
方法和
sorted()
内置函数。

list.sort()
是一个列表对象的方法,它会直接修改原列表,进行“原地”排序,并且不返回任何值(准确地说是返回
None
)。这就像你整理书架,直接把书在书架上重新排列,而不会搬到另一个地方整理。

my_list = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"原始列表: {my_list}")
my_list.sort() # 对原列表进行排序
print(f"排序后的列表 (list.sort()): {my_list}") # 输出: [1, 1, 2, 3, 4, 5, 6, 9]

# 降序排序也很简单
my_list = [3, 1, 4, 1, 5, 9, 2, 6]
my_list.sort(reverse=True)
print(f"降序排序后的列表: {my_list}") # 输出: [9, 6, 5, 4, 3, 2, 1, 1]

sorted()
是一个内置函数,它接受一个可迭代对象(不限于列表)作为参数,然后返回一个新的、已排序的列表,而原始的可迭代对象则保持不变。这就像你把书架上的书拍了张照,然后根据照片重新写了一份目录,书架上的书本身没动。

立即学习Python免费学习笔记(深入)”;

another_list = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"原始列表: {another_list}")
new_sorted_list = sorted(another_list) # 返回一个新的已排序列表
print(f"sorted()返回的新列表: {new_sorted_list}") # 输出: [1, 1, 2, 3, 4, 5, 6, 9]
print(f"原始列表 (未改变): {another_list}") # 输出: [3, 1, 4, 1, 5, 9, 2, 6]

# sorted()同样支持降序
new_desc_list = sorted(another_list, reverse=True)
print(f"sorted()降序返回的新列表: {new_desc_list}") # 输出: [9, 6, 5, 4, 3, 2, 1, 1]

这两个方法都默认进行升序排序。如果需要降序,只需将

reverse
参数设置为
True
即可。它们内部都使用了Timsort算法,这是一种混合排序算法,在实际应用中表现非常优秀,因为它结合了归并排序和插入排序的优点。

Python中in-place排序与创建新列表排序的区别是什么?

在我看来,理解

list.sort()
sorted()
之间最核心的差异,就是它们对内存和原始数据的影响。这不只是语法上的不同,更是编程思维和资源管理上的考量。

list.sort()
是典型的“原地(in-place)”操作。它直接在内存中修改了列表对象本身,没有创建新的列表。这意味着,如果你有一个非常大的列表,并且你确定不再需要其原始的未排序状态,那么使用
list.sort()
会更高效,因为它避免了创建新列表所需的额外内存开销。它的返回值为
None
,这其实是一个非常明确的信号:这个方法的主要作用是“副作用”(修改了对象),而不是“返回值”。我个人觉得,当你看到一个方法返回
None
时,潜意识里就应该知道它可能对调用者有直接影响。

反观

sorted()
函数,它则是一个“纯函数”的代表。它不触碰原始的可迭代对象,而是基于它创建一个全新的、已排序的列表并返回。这种方式的优点在于“无副作用”,原始数据始终保持完整。这在很多场景下非常有用,比如你需要保留原始列表以供后续其他操作,或者你正在编写一个函数,不希望意外地修改传入的参数。当然,这种做法的代价是需要额外的内存来存储新的列表。对于小型列表,这通常不是问题;但对于内存敏感的大型数据集,就得权衡一下了。

举个例子,假设你正在处理用户输入的一串数字,你既想展示排序后的结果,又想保留原始输入以便进行其他分析(比如计算平均值,而排序会打乱原始顺序)。这时,

sorted()
就是你的不二之选。但如果你的任务只是简单地对一个列表进行排序,然后就用排序后的结果,原始列表的顺序就不再重要,那么
list.sort()
无疑是更经济的选择。我有时候会纠结,到底用哪个,但通常会倾向于
sorted()
,除非我明确知道原地修改更优,因为“无副作用”的代码更容易理解和维护,也更不容易引入意外的bug。

Mokker AI
Mokker AI

AI产品图添加背景

下载

如何使用自定义规则对Python列表进行排序?

Python的排序功能远不止升序降序那么简单,它允许你通过

key
参数传入一个函数,来定义非常灵活的排序规则。这就像给排序算法提供了一个“翻译官”,告诉它“嘿,别直接比较元素本身,先用这个函数处理一下,然后根据处理后的结果来比较!”

这个

key
参数接受一个单参数函数,这个函数会对列表中的每个元素进行一次处理,然后排序算法会根据这些处理后的结果来决定元素的顺序。这对于排序包含复杂对象的列表特别有用。

最常见的用法是配合

lambda
表达式,实现简洁的自定义排序。

# 1. 排序字符串列表,忽略大小写
words = ["apple", "Banana", "cherry", "Date"]
# 默认排序会把大写字母排在前面
print(f"默认排序: {sorted(words)}") # 输出: ['Banana', 'Date', 'apple', 'cherry']
# 使用key=str.lower忽略大小写
print(f"忽略大小写排序: {sorted(words, key=str.lower)}") # 输出: ['apple', 'Banana', 'cherry', 'Date']

# 2. 排序元组列表,根据元组的第二个元素
students = [("Alice", 20, "Math"), ("Bob", 18, "Physics"), ("Charlie", 22, "Chemistry")]
# 默认排序是根据第一个元素
print(f"默认排序: {sorted(students)}")
# 根据年龄(第二个元素)排序
print(f"按年龄排序: {sorted(students, key=lambda student: student[1])}") # 输出: [('Bob', 18, 'Physics'), ('Alice', 20, 'Math'), ('Charlie', 22, 'Chemistry')]

# 3. 排序自定义对象列表
class Product:
    def __init__(self, name, price, stock):
        self.name = name
        self.price = price
        self.stock = stock
    def __repr__(self): # 为了打印时好看
        return f"Product({self.name}, ${self.price}, Stock:{self.stock})"

products = [
    Product("Laptop", 1200, 50),
    Product("Mouse", 25, 200),
    Product("Keyboard", 75, 100),
    Product("Monitor", 300, 30)
]

# 按价格排序
print(f"按价格排序: {sorted(products, key=lambda p: p.price)}")
# 按库存量排序 (降序)
print(f"按库存降序排序: {sorted(products, key=lambda p: p.stock, reverse=True)}")

# 4. 甚至可以按多个条件排序
# 先按价格升序,价格相同再按库存降序
# 注意:key函数返回一个元组,Python会按元组的顺序进行比较
print(f"按价格升序,库存降序: {sorted(products, key=lambda p: (p.price, -p.stock))}")
# 这里的-p.stock是为了实现降序,因为默认是升序比较

使用

key
参数时,你提供的函数会作用于列表中的每一个元素,生成一个用于比较的“代理值”。这个代理值可以是任何可比较的类型,比如数字、字符串、甚至元组。当
key
函数返回一个元组时,Python会按照元组元素的顺序进行逐个比较,直到找到不同的元素或者元组结束,这在处理多条件排序时非常强大。我个人觉得,掌握
key
参数的使用,是真正玩转Python排序的标志。

Python列表排序时,如何处理混合数据类型或复杂对象?

处理混合数据类型或者复杂对象的排序,确实是排序操作中比较有挑战性的一个方面。Python的默认排序机制,在面对不同类型的数据时,通常会因为无法确定比较规则而抛出

TypeError
。比如,你不能直接比较一个整数和一个字符串。

# 混合数据类型示例
mixed_list = [1, "hello", 3.14, "world", 2]
# sorted(mixed_list) # 这会抛出 TypeError: '<' not supported between instances of 'str' and 'int'

要解决这个问题,核心思路依然是利用

key
参数,为每种类型的数据提供一个统一的“可比较”的代理值。

1. 处理混合数据类型: 当列表包含多种类型的数据时,你可以编写一个

key
函数,根据元素的类型来返回一个适合比较的值。这通常涉及到为不同类型的数据定义一个“优先级”或者一个统一的表示。

mixed_list = [1, "hello", 3.14, "world", 2, "Python"]

def custom_key_for_mixed_types(item):
    if isinstance(item, int):
        return (0, item) # 整数优先级最高,然后按值排序
    elif isinstance(item, float):
        return (1, item) # 浮点数次之
    elif isinstance(item, str):
        return (2, item.lower()) # 字符串优先级最低,按小写字母排序
    else:
        return (3, str(item)) # 其他类型,转换为字符串处理

print(f"混合类型排序: {sorted(mixed_list, key=custom_key_for_mixed_types)}")
# 输出: [1, 2, 3.14, 'hello', 'Python', 'world']

这里,我给每种类型分配了一个优先级(元组的第一个元素),然后用元素本身(或其转换形式)作为元组的第二个元素。这样,Python在比较时,会先比较优先级,优先级相同再比较实际值。这是一种非常实用的策略。

2. 处理复杂对象(自定义类的实例): 对于自定义类的实例,如果没有特别指定,Python默认会比较它们的内存地址,这通常不是我们想要的。要让自定义对象可排序,有几种方法:

  • 使用

    key
    参数(最常用且推荐): 就像前面提到的
    Product
    例子,通过
    key=lambda obj: obj.attribute
    来指定根据哪个属性进行排序。这是最灵活和非侵入性的方法。

  • 实现特殊方法

    __lt__
    等: 如果你希望你的自定义对象在任何情况下都能直接进行比较(比如
    obj1 < obj2
    ),那么可以在类中实现富比较方法,特别是
    __lt__
    (less than)。Python的
    functools.total_ordering
    装饰器可以帮助你减少代码量,只需要实现
    __lt__
    和一个相等方法(
    __eq__
    ),它就能自动为你生成其他比较方法。

    from functools import total_ordering
    
    @total_ordering
    class Book:
        def __init__(self, title, author, pages):
            self.title = title
            self.author = author
            self.pages = pages
    
        def __repr__(self):
            return f"Book('{self.title}', '{self.author}', {self.pages}页)"
    
        def __eq__(self, other):
            if not isinstance(other, Book):
                return NotImplemented
            return (self.title, self.author, self.pages) == \
                   (other.title, other.author, other.pages)
    
        def __lt__(self, other): # 定义小于操作,这里按页数排序
            if not isinstance(other, Book):
                return NotImplemented
            return self.pages < other.pages
    
    books = [
        Book("Python Crash Course", "Eric Matthes", 544),
        Book("Fluent Python", "Luciano Ramalho", 912),
        Book("Automate the Boring Stuff", "Al Sweigart", 500)
    ]
    
    print(f"按页数排序 (__lt__): {sorted(books)}")
    # 输出: [Book('Automate the Boring Stuff', 'Al Sweigart', 500页), Book('Python Crash Course', 'Eric Matthes', 544页), Book('Fluent Python', 'Luciano Ramalho', 912页)]

    这种方式的好处是,一旦定义了比较规则,你的对象就可以在任何需要比较的地方直接使用,而不仅仅是排序。但缺点是,它将排序逻辑“硬编码”到了类定义中,如果需要多种排序方式,可能就得回到

    key
    参数了。我通常会根据对象的“自然顺序”来决定是否实现
    __lt__
    ,如果对象有一个非常明确的主导排序属性,那就实现它;否则,
    key
    参数是更灵活的选择。

在处理这些复杂场景时,关键在于把不同类型或复杂对象“映射”到一个可比较的统一形式。这个映射过程就是

key
函数的工作。这确保了排序算法总能拿到它能理解和处理的数据,避免了类型不匹配带来的混乱。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Sass和less的区别
Sass和less的区别

Sass和less的区别有语法差异、变量和混合器的定义方式、导入方式、运算符的支持、扩展性等。本专题为大家提供Sass和less相关的文章、下载、课程内容,供大家免费下载体验。

216

2023.10.12

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

338

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

225

2025.10.31

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

138

2026.02.12

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

409

2023.09.04

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1567

2023.10.24

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号