列表实战——就地改变列表——关于列表排序的更多知识

未匹配的标注

另一个常见方法 sort就地排序列表;它使用Python标准比较测试(这里,字符串比较,但可用于每一种对象类型),并默认按升序排序。可通过传入关键字参数——函数调用的一个特殊的“name=value”语法(指定按名称传递参数,且常用来给出配置选项)——来修改排序行为。

在排序中,reverse排序允许按降序而非升序排序,key参数给出一个单参数的返回值用于排序的函数——下面例子中字符串对象的标准 lower大小写转换函数(虽然其更新的casefold可能更好地处理一些Unicode文本类型):

>>> L = ['abc', 'ABD', 'aBe']
>>> L.sort() # Sort with mixed case
>>> L
['ABD', 'aBe', 'abc']
>>> L = ['abc', 'ABD', 'aBe']
>>> L.sort(key=str.lower) # Normalize to lowercase
>>> L
['abc', 'ABD', 'aBe']
>>>
>>> L = ['abc', 'ABD', 'aBe']
>>> L.sort(key=str.lower, reverse=True) # Change sort order
>>> L
['aBe', 'ABD', 'abc']

当对字典列表排序时,sort的 key 参数也可能很有用(通过索引每个字典挑出一个排序键)。在本章稍后将研究字典,然后将在第4部分学习更多关于关键字函数参数的知识。

这里有一个警告:小心 appendsort都是就地修改相关的列表对象,但不返回这个列表作为结果(技术上讲,它们都返回一个叫做 None的值)。如果你说类似 L=L.append(X),不会得到L的修改值(事实上,将完全丢失对列表的引用!)当使用如appendsort属性时,作为副作用:对象被修改,所以没有理由再次赋值。

部分因为这些限制,排序在最新版本的Python中也作为内置函数而可用了,它对任何集合(不只列表)进行排序,并返回新列表作为结果(而非就地改变):

>>> L = ['abc', 'ABD', 'aBe']
>>> sorted(L, key=str.lower, reverse=True) # Sorting built-in
['aBe', 'ABD', 'abc']
>>> L = ['abc', 'ABD', 'aBe']
>>> sorted([x.lower() for x in L], reverse=True) # Pretransform items: differs!
['abe', 'abd', 'abc']

注意这里的最后一个例子——可以使用列表comprehension在排序前转换为小写,但结果不会像使用key关键字那样包含原来的列表值。后者在排序中临时转换为小写,而非完全地改变被排序的值。随着继续学习,将看到 sorted内置函数有时会被 sort方法更有用的情形。


注意

3.X中的比较和排序:在Python 2.X 中,不同类型对象(比如:字符串和列表)的相对值比较也是可以的——语言在不同类型之间定义了固定排序,它不美观,但是决定性的。也就是说,排序基于类型涉及的名称:比如,所有整数都被所有字符串要小,因为 "int" 小于 "str"。比较从不自动转换类型,除了当比较数字类型对象时。

在Python 3.X中,这已经改变了:混合类型的数值比较会抛出异常而非退回到固定的跨类型排序上。因为排序在内部使用比较,这意味着 [1, 2, 'spam'].sort() 在Python 2.X中会成功,但在3系列中将抛出异常。通过代理对混合类型排序也会失败。

Python 3.X 还不再支持传入任意比较函数来排序(实现不同的顺序)。建议的变通方法在排序中是使用 key=func关键字参数来对值的转换进行编码,并使用 reverse=True关键字参数来改变排序顺序为降序。这些是过去比较函数的典型应用。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~