编程后端开发工程师

Python 中的 sort() 方法是如何工作的,它与 sorted() 函数有什么区别,有哪些重要的参数、使用细节和可能的陷阱?

用 Hintsage AI 助手通过面试

回答

问题历史: sort() 方法自 Python 的早期版本以来就内置于 list 类型中,而 sorted() 函数是在 Python 2.4 中引入的。排序集合是编程中最常见的任务之一,Python 提供了两种基本工具来解决这个问题。

问题: 许多初学者会混淆 sort()(列表方法)和 sorted()(高级功能)。他们对何时使用就地排序、可以排序的对象、如何通过 key/reverse 设定自定义顺序以及这可能导致的陷阱,尤其是对于复杂的用户结构,缺乏理解。

解决方案:

  • list.sort() 在原地排序,并返回 None。改变原始对象。
  • sorted() 返回一个新的已排序列表(或者如果传递其他类型,则返回其他类型),不改变原始对象。它适用于任何可迭代对象(甚至生成器)。
  • 两种方法都支持 key(排序函数)和 reverse(在相反顺序排序的布尔标志)参数。

代码示例:

numbers = [5, 2, 9, 1] numbers.sort() # numbers = [1, 2, 5, 9] words = ['aaa', 'ZZZ', 'bbb'] sorted_words = sorted(words, key=str.lower, reverse=True) # sorted_words = ['ZZZ', 'bbb', 'aaa'] # words 保持不变

关键特性:

  • sort() 仅适用于列表并在原地排序,而 sorted() 更通用——适用于任何可迭代对象。
  • 通过 key 参数自定义排序——方便按 lambda 或对象属性排序。
  • 重要的是不要混淆,sort 返回 None,这常常导致意外赋值时的错误。

令人困惑的问题。

如果执行 my_list = my_list.sort(),变量将返回什么?

答案:my_list 将为 None,因为 sort 在原地排序列表并返回 None。这是一个常见的错误:始终在不赋值的情况下就地排序,或者如果需要将已排序对象作为新列表,则使用 sorted。

代码示例:

lst = [3, 1, 2] lst = lst.sort() # lst 现在是 None

可以使用 sort() 方法对元组或字符串进行排序吗?

答案:不能,因不可变对象(tuple, str)没有 sort 方法,但可以使用 sorted(),它返回一个包含元素的新排序列表。

代码示例:

tpl = (4, 2, 7) sorted_tpl = sorted(tpl) # sorted_tpl = [2, 4, 7]

可以对具有不同类型元素的列表进行排序吗?

答案:在 Python 3 中,对不同不可比较类型(例如 int 和 str)的排序会引发 TypeError。在 Python 2 中有特定的顺序,现在需要明确指定 key 函数,以将所有值总结为可比较的形式。

常见错误和反模式

  • 混淆了 sort/sorted 的返回值——数据丢失。
  • 尝试在没有 key 的情况下对不可比较的对象进行排序——将引发异常。
  • 在需要“原始”副本时中对大集合进行原地排序。
  • 使用重的 key 函数,显著减慢排序速度。

现实案例

负面案例

程序员执行了 my_list = my_list.sort(),因此失去了对原始列表的访问,因为变量被赋值为 None。

优点:

  • 语法看起来“合乎逻辑”(对初学者)

缺点:

  • 数据访问的丧失,容易在大型项目中未注意到错误,导致程序在运行时崩溃。

正面案例

使用正确的 sorted() 获取新版本而不改变原始的,或者正确定义 sort,而不进行赋值。

优点:

  • 明确的行为,保持原始数据的完整性。
  • 对可迭代对象(而不仅仅是列表)具有灵活性。

缺点:

  • 使用 sorted 创建副本——对非常大的集合会增加内存开销。