6.12 操作符

6.12.1 标准类型操作符

在第4章里,我们介绍了一些适用于包括标准类型在内的大部分对象的操作符,现在我们来看一下这些操作符如何作用在列表上。

6.12 操作符 - 图1

在使用比较操作符时,比较数字和字符串是很明了的,但是用在列表上时就不是那么简单了。列表比较操作有些狡猾,但是合乎逻辑。比较列表时也是用的内建的cmp()函数,基本的比较逻辑是这样的:两个列表的元素分别比较,直到有一方的元素胜出,比如我们上面的例子,‘abc’和‘xyz’的比较直接决定了比较结果,在‘abc’<‘xyz’时,list1<list2,list2>=list3,元组类型在进行比较操作时跟列表遵循相同的逻辑。

6.12.2 序列类型操作符

1. 切片([]和[:])

列表的切片操作跟字符串的切片操作很像,不过列表的切片操作返回的是一个对象或者是几个对象的集合,而不是像字符串那样,返回一个字符或者一个子串。我们定义以下几个列表用来做例子。

6.12 操作符 - 图2

列表的切片操作也遵从正负索引规则,也有开始索引值,结束索引值,如果这两个值为空,默认也会分别指到序列的开始和结束位置。

6.12 操作符 - 图3

跟字符串类型只能用字符为元素不同,列表类型的元素可以是另一个序列类型,这就意味着你在列表的元素上也可以使用所有的序列操作符或者在其上执行序列类型内建的各种操作。在下面的例子中,我们将会展示,不仅可以在一个切片操作的结果之上再进行切片,而且还可以改变这个切片的结果,即使新对象的类型跟原对象不同也可以。你会注意到,这跟多维数组有一些类似。

6.12 操作符 - 图4

这时用num_list来做的另一个例子:

6.12 操作符 - 图5

注意在最后一个例子中,我们是如何把列表的单一元素替换成一个列表。在列表中进行诸如remove、add和replace的操作是多么的自由了吧!还有一点要注意,如果你想以子列表的形式得到一个列表中的一个切片,那需要确保在赋值时等号的左边也是一个列表而不是一个列表的元素。

2. 成员关系操作(in not in)

列表中(同样适用于元组),我们可以检查一个对象是否是一个列表(或者元组)的成员。

6.12 操作符 - 图6

注意,‘x’并不属于mixup_list,因为‘x’本身并不是mixup_list的一个成员,而是mixup_list[1]的,mixup_list[1]也是一个列表类型。成员关系操作运算同样适用于元组类型。

3. 连接操作符(+)

连接操作符允许我们把多个列表对象合并在一起。注意,列表类型的连接操作也只能在同类型之间进行,换句话说,你不能把两个不同类型的对象连接在一起,即便他们都是序列类型也不行。

6.12 操作符 - 图7

在6.23节里面我们会讲到,从Python 1.5.2起,我们可以用extend()方法来代替连接操作符把一个列表的内容添加到另一个中去。使用extend()方法比连接操作的一个优点是它实际上是把新列表添加到了原有的列表里面,而不是像连接操作那样新建一个列表。list.extend()方法也被用来做复合赋值运算,也就是Python 2.0中添加的替换连接操作(+=)。

必须指出,连接操作符并不能实现向列表中添加新元素的操作。在接下来的例子中,我们展示了一个试图用连接操作向列表中添加新元素而报错的例子。

6.12 操作符 - 图8

这个例子之所以是错误的,是因为我们在连接操作符的左右两边使用了不同类型的值,列表类型+字符串类型这样的操作是非法的。显然,我们的初衷是把一个字符串作为一个新元素添加到列表中去,不过我们的方法不正确。幸运的是,我们有一个正确的方法:

使用内建函数append()(我们会在6.13节里面正式地介绍append()和其他内建函数)。

6.12 操作符 - 图9

4. 重复操作符(*)

重复操作符可能更多地应用在字符串类型中,不过,列表和元组跟字符串同属序列类型,所以需要的时候也可以使用这一操作。

6.12 操作符 - 图10

Python 2.0起,也开始支持复合赋值运算。

6.12 操作符 - 图11

6.12.3 列表类型操作符和列表解析

其实Python中没有专门用于列表类型的操作符。列表可以使用大部分的对象和序列类型的操作符。此外,列表类型有属于自己的方法。列表才有的构建——列表解析。这种方法是结合了列表的方括弧和for循环,在逻辑上描述要创建的列表的内容。我们在第八章讨论列表解析,这里仅仅向本章其他地方所做的那样,展示一个简单的例子:

6.12 操作符 - 图12