6.14 列表类型的内建函数

Python中的列表类型有自己的方法。我们会在第13章面向对象编程里面正式而详细的介绍方法这一概念,现在你只需要把方法视为特定对象的函数或者过程就好。本节讨论的方法就像内建的函数一样,除了它们只对列表类型进行操作之外。因为这些函数涉及到对列表更改(或者说更新),所以它们都不适应于元组。

你可以重温一下我们前面讲到的用点号的方式访问对象的属性object.attribute列表的方法也是这样:list.method()。我们用点号来访问一个对象的属性(在这里是一个函数),然后用函数操作符(())来调用这个方法。

我们可以在一个列表对象上应用dir()方法来得到它所有的方法和属性。

6.14 列表类型的内建函数 - 图1

6.14 列表类型的内建函数 - 图2

表6.11列出了目前列表类型支持的所有方法,稍后我们给出使用这些方法的例子。

6.14 列表类型的内建函数 - 图3

6.14 列表类型的内建函数 - 图4

在前面的例子中,我们用一个元素初始化了一个列表,然后当向列表插入元素,或在尾部追加新的元素后,都会去检查这个列表。现在确认一下一个值是否在我们的列表中,并看看如何找出元素在列表中的索引值。我们用in操作符和index()方法实现这两个需求。

6.14 列表类型的内建函数 - 图5

6.14 列表类型的内建函数 - 图6

噢!最后一个例子怎么出错了?呃,看起来用index()来检查一个元素是否存在于一个list中并不是个好主意,因为我们出错了。应该先用in成员关系操作符(或者是not in)检查一下,然后在用index()找到这个元素的位置。我们可以把最后几个对index()调用放到一个单独的for循环里面,像这样:

6.14 列表类型的内建函数 - 图7

这个方案避免了我们上面犯的错误,因为在确认一个元素属于该列表之前index()方法是不会被调用的。稍后我们将会发现该如何处理这种错误,而不是这样的一出错,程序就崩溃了。

接下来我们测试sort()和reverse()方法,它们会把列表中的元素排序,然后翻转。

6.14 列表类型的内建函数 - 图8

6.14 列表类型的内建函数 - 图9核心笔记:那些可以改变对象值的可变对象的方法是没有返回值的

Python初学者经常会陷入一个误区:调用一个方法就返回一个值。最明显的例子就是sort()。

6.14 列表类型的内建函数 - 图10

在使用可变对象的方法如sort()、extend()和reverse()的时候要注意,这些操作会在列表中原地执行操作,也就是说现有的列表内容会被改变,但是没有返回值!是的,与之相反,字符串方法确实有返回值。

6.14 列表类型的内建函数 - 图11

温习一下,字符串是不可变的——不可变对象的方法是不能改变它们的值的,所以它们必须返回一个新的对象。如果你确实需要返回一个对象,那么我们建议你看一下Python2.4以后加入的reversed()和sorted()内建函数。

它们像列表的方法一样工作,不同的是它们可以用做表达式,因为它们返回一个对象。同时原来的那个列表还是那个列表,没有改变,而你得到的是一个新的对象。

回到sort()方法,它默认的排序算法是归并排序(或者说“timsort”)的衍生算法,时间复杂度是O(lg(n!))。关于这个算法我们不做进一步的讲解,可以通过源码查看它们的详情——Objects/listobject.c,还有算法描述:Objects/listsort.txt。

extend()方法接受一个列表的内容然后把它的所有元素追加到另一个列表中去:

6.14 列表类型的内建函数 - 图12

从2.2开始,extend()方法的参数支持任何可迭代对象。在2.2之前,它的参数必须是序列对象,而在1.6之前它的参数必须是列表对象。通过可迭代对象(而不是一个序列对象),你能做更多有趣的事情,比如:

6.14 列表类型的内建函数 - 图13

  1. 5.2中加入的pop()方法会从列表中把最后的或指定的元素返回调用者。我们会在6.15.1节和练习中看到pop()方法。