Python 中的列表(list)、元组(tuple)和字符串(str)等序列类型都支持切片操作。
1 最后一个元素设计
切片操作时不会包含区间范围中的最后一个元素,因为 Python 与 Java 语言一样,以 0 作为起始下标。这样做的好处是:
- 当看见
[:x]
语法时,就可以知晓切片内包含 x 个元素。 - 当看见
[start:stop]
语法时,就可以知晓切片内包含 stop-start 个元素。 - 通过一个下标就可以把序列分割成不重叠的两部分,形如
my_list[:x]
(范围为 0 ~ x-1)和my_list[x:]
(范围为 x ~ len-1)。
l=[10, 20, 30, 40, 50, 60]
logging.info('l[:2] -> %s',l[:2])
logging.info('l[2:] -> %s',l[2:])
logging.info('l[:3] -> %s',l[:3])
logging.info('l[3:] -> %s',l[3:])
logging.info('l[1:2] -> %s',l[1:2])
运行结果:
INFO - l[:2] -> [10, 20]
INFO - l[2:] -> [30, 40, 50, 60]
INFO - l[:3] -> [10, 20, 30]
INFO - l[3:] -> [40, 50, 60]
INFO - l[1:2] -> [20]
2 按间隔切片
我们还可以用 s [ a : b : c ]
的语法对 s 中的在 a 和 b 之间的元素以 c 为间隔切片。 c 值如果为负,则会进行反向取值。
s='python'
logging.info('s[::3] -> %s',s[::3])
logging.info('s[::-1] -> %s',s[::-1])
logging.info('s[::-2] -> %s',s[::-2])
运行结果:
INFO - s[::3] -> ph
INFO - s[::-1] -> nohtyp
INFO - s[::-2] -> nhy
3 操作切片
把切片放在赋值语句的左边,就可以直接修改序列。如果把它作为 del 操作的对象,我们就可以对序列进行切除操作。
Luciano Ramalho 举了这样一个示例:
l=list(range(10))
logging.info('l -> %s',l)
l[2:5]=[20,30]
logging.info('l -> %s',l)
del l[5:7]
logging.info('l -> %s',l)
l[3::2]=[11,22]
logging.info('l -> %s',l)
l[2:5]=[100]
logging.info('l -> %s',l)
l[2:5]=100
运行结果:
INFO - l -> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
INFO - l -> [0, 1, 20, 30, 5, 6, 7, 8, 9]
INFO - l -> [0, 1, 20, 30, 5, 8, 9]
INFO - l -> [0, 1, 20, 11, 5, 22, 9]
INFO - l -> [0, 1, 100, 22, 9]
Traceback (most recent call last):
...
l[2:5]=100
TypeError: can only assign an iterable
如果赋值的对象是一个切片,那么它必须是个可迭代对象。即便只有一个值,也必须要把它转换成可迭代的序列。比如示例中的最后一个例子直接把 100 赋值给 l[2:5]
,Python 就会抛出 TypeError: can only assign an iterable 错误。