说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python 切片就是在序列对象(字符串、元组或列表)中选择某个范围内的项。 切片可被用作表达式以及赋值或 del 语句的目标。
首先,在 Python 中,切片是获取部分数据,这部分数据可以是:
字符串等序列支持 索引 (下标访问),第一个字符的索引是 0。单个值称为索引操作,取多个值(形式上的,实际可能取到单值或者取不到值)为切片操作。
序列元素的编号左从 0 开始,右从 -1 开始,形如:
0 1 2 3 4 # 索引位置
+---+---+---+---+---+
| H | e | l | l | o |
+---+---+---+---+---+
0 1 2 3 4 5 # 切片位置
-5 -4 -3 -2 -1
还可以这样理解切片,索引指向的是字符 之间 ,第一个字符的左侧标为 0,最后一个字符的右侧标为 n ,n 是字符串长度。例如上方最右的 5 就是长度。
Python 的切片语法有:
a[start:stop] # 从开始到 stop-1
a[start:] # 从 start 开始的其余部分
a[:stop] # items from the beginning through stop-1
a[:] # a copy of the whole array
a[start:stop:step] # start through not past stop, by step
参数说明:
要记住的关键点是:stop 值表示不在选定切片中的第一个值。因此,stop 和 start 之间的差异是所选元素的数量(如果 step 默认为 1)。
根据切片的性质和语法,我们来进行序列的查询,以字符串为例,其他的序列道理是一样的。要注意的是单字符没有专用的类型,就是长度为一的字符串,空字符(序列)没有索引。
先上一个索引图示:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
还可以这样理解切片,索引指向的是字符 之间 ,第一个字符的左侧标为 0,最后一个字符的右侧标为 n ,n 是字符串长度。
第一行数字是字符串中索引 0...6 的位置,第二行数字是对应的负数索引位置。i 到 j 的切片由 i 和 j 之间所有对应的字符组成。
首先,先看看索引操作,示例操作如下:
word = 'Python'
word[0] # 位置0中的字符
# 'P'
word[5] # 位置5中的字符
# 'n'
# 支持负值
word[-1] # 末字符
# 'n'
word[-2] # 倒数第二个字符
# 'o'
word[-6]
# 'P'
注意,-0 和 0 一样,因此,负数索引从 -1 开始。
以上是索引操作,可以认为是选择单个。如果要选择多个,字符串还支持 切片。索引可以提取单个字符,切片 则提取子字符串:
word[0:2] # 从位置0(包括)到2(不包括)的字符
# 'Py'
word[2:5] # 从位置2(包括)到5(不包括)的字符
# 'tho'
切片索引的开始结束值可以省略,省略开始索引时,默认值为 0,省略结束索引时,默认为到字符串的结尾:
word[:2] # 从开头到位置2的字符(不包括)
# 'Py'
word[4:] # 从位置4(包括)到结尾的字符
# 'on'
word[-2:] # 从倒数第二个(包括)到结尾的字符
# 'on'
如果设定步长则不能省略开始和结束,如果确定不需要开始和结束,可以用 : 号占位:
word[2:6:2] # 步长为2
# 'to'
word[::2] # 不指定开始结束
# 'Pto'
步长还可以为负,表示反向取值:
word[-1:-5:-1]
# 'noht'
word[::-1] # 反转序列的技巧
# 'nohtyP'
还可以对序列连续操作切片:
word[::-1][1:3]
# 'oh'
对于使用非负索引的切片,如果两个索引都不越界,切片长度就是起止索引之差。例如, word[1:3] 的长度是 2。
索引越界会报错:
word[42] # 这个单词只有6个字符
'''
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
'''
但是,切片会自动处理越界索引:
word[4:42]
# 'on'
word[42:]
# ''
Python 字符串等类型不能修改,是不可变(immutable)的。因此,为字符串中某个索引位置赋值会报错:
word[0] = 'J'
# TypeError: 'str' object does not support item assignment
word[2:] = 'py'
# TypeError: 'str' object does not support item assignment
要生成不同的字符串,应新建一个字符串:
'J' + word[1:]
# 'Jython'
word[:2] + 'py'
# 'Pypy'
对于可变序列,切片选择数据可以进行赋值修改。例如列表:
cubes = [1, 8, 27, 65, 125] # something's wrong here
4 ** 3 # the cube of 4 is 64, not 65!
# 64
cubes[3] = 64 # replace the wrong value
cubes
# [1, 8, 27, 64, 125]
cubes[::2] = [0, 0, 0]
cubes
# [0, 8, 0, 65, 0]
cubes[::2] = range(3)
cubes
# [0, 8, 1, 65, 2]
全选后可以赋值清空序列及删除部分内容:
cubes = [1, 8, 27, 65, 125]
cubes[:] = []
cubes
# []
cubes = [1, 8, 27, 65, 125]
cubes[1:3] = []
cubes
# [1, 65, 125]
对带有步长的切片赋值操作,好像不支持数量不同的项。
cubes[::2] = range(2)
# ValueError: attempt to assign sequence
# of size 2 to extended slice of size 3
cubes[::2] = []
# ValueError: attempt to assign sequence
# of size 0 to extended slice of size 3
这是为了一致性,Python 禁止所有扩展的切片赋值,除非已经有了该值的位置。
常规切片的步长始终为1,因此不可能出现任何间隙,因此可以安全地允许赋值。
使用 del 语句可以同删除选中的切片内容:
cubes = [1, 8, 27, 65, 125]
del cubes[1:3]
cubes
# [1, 65, 125]
# 支持步长
cubes = [1, 8, 27, 65, 125]
del cubes[::2]
cubes
# [8, 65]
Python 内置函数 slice() 返回一个切片对象,用于切取任何序列,详细内容可以访问教程:Python slice() 切片对象。
扩展切片(带逗号和省略号)主要只用于特殊数据结构(如 NumPy),基本序列不支持它们。
>>> class slicee:
... def __getitem__(self, item):
... return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
支持切片的数据类型为内置 sequence 类型,内置的序列类型有 list、str、tuple 和 bytes 等。
同时,实现了序列协议的自定义数据也支持切片,可以访问教程: Python 序列类型,查看如何实现序列协议。
更新时间:2024-06-09 09:24:19 标签:python 切片 序列