通用的序列操作 #################################### Python 内置了多种序列,其中最常用的是:列表、元组和字符串(字符串就是由字符组成的序列)。 列表和元组的主要不同在于,列表是可以修改的,而元组不可以修改。在编写程序时,几乎所有情况下都可使用列表来代替元组,一种例外情况是作为字典的键时只能是元组而不能是列表,因为字典的键是不可变的。 通用的序列操作包括索引、切片、相加、相乘和成员资格检查等。另外,Python 还提供了一些内置函数,可用于确定序列的长度以及找出序列中最大和最小的元素等。 序列索引 ************************************ 序列中的所有元素都有编号(从 0 开始递增),这称为索引(indexing),你可使用索引来获取元素。这种索引方式适用于所有序列。当你使用负数索引时,Python 将从右(即从最后一个元素)开始往左数,因此 -1 是最后一个元素的位置。你可像下面这样来访问各个元素: .. highlight:: none :: >>> greet = 'Hello World' >>> greet[0] 'H' >>> greet[-1] 'd' 所有的序列都可直接对其执行索引操作,无需先将其赋值给变量。这与先赋值给变量再对变量执行索引操作是一样的。如果函数调用返回一个序列,可直接对其执行索引操作。 :: >>> 'Hello'[1] 'e' >>> fourth = input('Year: ')[3] Year: 2019 >>> fourth '9' 序列切片 ************************************ 除使用索引来访问单个元素外,还可使用切片(slicing)来访问特定范围内的元素。切片适用于提取序列的一部分,其中的编号非常重要,第一个索引指定的元素包含在切片内,但第二个索引指定的元素不包含在切片内。请看下面的示例: :: >>> greet = 'Hello World' >>> greet[2:5] 'llo' >>> greet[3:-2] 'lo Wor' >>> greet[0:1] 'H' .. note:: 切片值与原序列的类型是相同的,列表的切片值是列表,字符串的切片值是字符串。即使切片只提取一个元素,仍将如此,在调用切片时请格外注意! 绝妙的简写 ==================================== 假设要截取列表中的最后三个元素,第二个索引值必须大于列表中元素的总数,才可以提取到最后一个元素,虽然它并不存在,但这种方法确实可以达到目的。 :: >>> greet[8:11] 'rld' 如果使用负数索引,索引值 -1 无法包含最后一个元素。如果使用索引0,即到达列表末尾后再前进一步,结果将如何呢? :: >>> greet[-3:-1] 'rl' >>> greet[-3:0] '' 结果并不理想。事实上,执行切片操作时,如果第一个索引指定的元素位于第二个索引指定的元素后面(如上例),结果就为空序列。 .. note:: 在使用负数索引作为开始索引时,在极个别的情况下,会出现奇怪的结果。例如,当索引为 -0 时,也会返回原序列。 :: >>> greet = 'Hello World' >>> greet[-0:] 'Hello World' 切片提供了一种什么都不写的简写方式,实现提取到最后一个元素的操作。如果切片结束于序列末尾,可省略第二个索引。如果切片开始于序列开头,也可省略第一个索引。 :: >>> greet[-3:] 'rld' >>> greet[:3] 'Hel' # 要复制整个序列,可将两个索引都省略 >>> greet[:] 'Hello World' 更大的步长 ==================================== 切片操作实际上有三个参数,但通常会省略第三个参数,即步长参数。默认为 1,这意味着从一个元素移到下一个元素,因此切片包含起点和终点之间的所有元素。还可以指定步长,如果指定的步长大于 1,将跳过一些元素。例如:步长为 2 时,将从起点和终点之间每隔一个元素提取一个元素。 :: >>> greet[0:11:1] 'Hello World' >>> greet[0:11:2] 'HloWrd' >>> greet[0:11:3] 'HlWl' >>> greet[::4] 'Hor' 步长不能为 0,否则无法向前移动,但可以为负数,即从右向左提取元素。在这种情况下,要正确地提取元素颇费思量。此时,第一个索引依然包含在内,而第二个索引不包含在内。步长为负数时,第一个索引必须比第二个索引大。当省略起始和结束索引时,步长为正数时,它从起点移到终点,当步长为负数时,它从终点移到起点。 :: >>> greet[0:11:-2] '' # 切片值依然不会提取结束索引位置的元素 >>> greet[11:0:-1] 'dlroW olle' >>> greet[11:0:-2] 'drWol' >>> greet[::-3] 'dooe' >>> greet[5::-2] ' le' >>> greet[:5:-2] 'drW' 序列相加 ************************************ 可使用加法运算符来拼接相同类型的序列。但是不能拼接列表 + 字符串。 :: >>> 'Hello ' + 'World' 'Hello World' >>> [1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] >>> [1, 2, 3] + 'World' Traceback (most recent call last): File "", line 1, in TypeError: can only concatenate list (not "str") to list 序列相乘 ************************************ 将序列与数字相乘时,将重复这个序列 n 次来创建一个新序列: :: >>> 'Hello ' * 5 'Hello Hello Hello Hello Hello ' >>> [6] * 3 [6, 6, 6] 成员资格 ************************************ 运算符 in 检查指定的对象是否是序列的成员(即其中的一个元素),并返回相应的值:满足时返回 True;不满足时返回 False。 :: >>> greet = 'Hello World' >>> 'H' in greet True >>> "Wor" in greet True >>> 'a' in greet False >>> 'llo ' in greet True # 开头添加了空格 >>> ' llo ' in greet False >>> numbers = [1, 2, 3, 4, 5, 6, 7] >>> 2 in numbers True # 不能检查切片是否包含在序列中 >>> [2, 3] in numbers False 查找元素的次数、元素的索引 ************************************ count 和 index 都是序列的方法,count 用于统计某个元素在列表中出现的次数,index 从序列中查找指定值第一次出现的索引。 :: >>> greet = 'Hello World' >>> greet.count('l') 3 >>> greet.index('l') 2 >>> greet.index('o') 4 长度、最小值和最大值 ************************************ 内置函数 len 返回序列中所包含的元素总数,而 min 和 max 分别返回序列中最小和最大的元素。 :: >>> numbers = [100, 34, 678] >>> len(numbers) 3 >>> max(numbers) 678 >>> min(numbers) 34 >>> max(2, 3) 3 >>> min(9, 3, 2, 5) 2 序列解包 ************************************ 一次给多个变量赋值的方法,称为序列解包,但是需保证赋值运算符左右两边的元素数目相等。 :: >>> a, b, c = (1, 2, 3) >>> a 1 >>> b 2 >>> c 3 序列解包还可以利用 ``*`` 表达式将多个元素赋值给一个变量(获取的值默认为 list)。 :: # 获取剩余部分 >>> a, b, *c = 0, 1, 2, 3 >>> a 0 >>> b 1 >>> c [2, 3] # 获取中间部分 >>> a, *b, c = 0, 1, 2, 3 >>> a 0 >>> b [1, 2] >>> c 3 # 如果左值比右值多,带 * 的变量默认为空 >>> a, b, *c = 0, 1 >>> a 0 >>> b 1 >>> c [] >>> a, *b, c = 0, 1 >>> a 0 >>> b [] >>> c 1 # 嵌套解包 >>> (a, b), (c, d) = (1, 2), (3, 4) >>> a 1 >>> b 2 >>> c 3 >>> d 4 >>> a, b, c, d (1, 2, 3, 4)