想把列表排好序,写下 numbers = numbers.sort(),结果 numbers 反而成了 None。这不是排序失败,而是把“修改原对象”和“返回新结果”混为一谈。我用几组小数据,把这两个动作拆开验证。
排序成功了,接住的却不是列表
numbers = [3, 1, 2] alias = numbers result = numbers.sort() print(numbers) # [1, 2, 3] print(result is None) # True print(alias is numbers) # True
在 Python 3.14.7 中实际执行,以上结果全部成立:原列表已经排好,另一个引用也看到了变化,但方法返回的是 None。因此,把调用结果再赋给 numbers,会让这个变量改为指向 None;不是原列表被排序“弄没了”。
Python 官方排序指南明确区分了这两条路径:list.sort() 原地修改列表并返回 None;sorted() 则构造新的排序列表。这里需要选择的是修改边界,不只是把函数名换一下。
想保留原顺序,就明确创建新列表
original = [3, 1, 2] ordered = sorted(original) print(original) # [3, 1, 2] print(ordered) # [1, 2, 3] print(ordered is original) # False
这组实验没有改动 original 的顺序。我的选择很简单:只需要把手头列表排好,就单独写 original.sort(),不要接它的返回值;原顺序还有用途,就写 ordered = sorted(original)。
新列表不等于把内部对象也复制一遍
rows = [{'score': 2}, {'score': 1}]
ordered = sorted(rows, key=lambda row: row['score'])
ordered[0]['score'] = 9
print(rows[1]['score']) # 9
我也执行了这个反例:排序创建了新的外层列表,但里面仍然引用原来的字典。它保护的是原列表的排列顺序,不是为内部对象建立独立副本。如果后续还要修改字典或嵌套列表,应另行决定复制策略,不能把 sorted() 当成深复制。
结论:遇到“排序后变 None”,先检查是不是把原地方法的返回值赋回变量;需要保留原顺序,再使用 sorted()。至于内部对象能否共享,是另一个必须单独回答的问题。
本文是合成数据小实验与 AI 辅助整理,不是线上事故复盘,也没有测试性能优劣。实验使用 Python 3.14.7;官方资料于 2026 年 10 月 14 日核对,所读文档为 Python 3.14 分支,当日页面标示 3.14.8,未将其当作本机运行版本。