字符实战——索引和切片
因为字符串被定义为多个字符的有序集合,所以可通过位置来访问它们的组成部分。在 Python 中,字符串中的字符是通过索引来获取的 —— 在字符串后的方括号中提供想要的组成部分的数字偏移量。在指定位置获得单字符的字符串。
和在 C 语言中一样,Python 的偏移量是从 0 开始,在字符串长度 - 1 的地方结束。然而,不像 C 语言,Python 还允许使用负偏移从序列如字符串中获取项。技术上讲,负偏移被添加到字符串长度上从而得出正偏移。可以将负偏移想为从末尾向后数。下面的交互展示了:
>>> S = 'spam'
>>> S[0], S[−2] # 从前面或后面索引
('s', 'a')
>>> S[1:3], S[1:], S[:−1] # 切片:提取一段
('pa', 'pam', 'spa')
第一行定义了一个 4 字符的字符串并将它分配给名称 S。下一行用两种方法来索引它:S [0] 从左边获取在偏移量 0 处的项 —— 单字符串 'S';S [-2] 从末尾获取在反向偏移量 2 处的项 —— 或等价地,从前面的偏移 (4+(-2))
处。更形象的说,偏移和切片映射到图 7-1 中所显示的单元格:
前面例子的最后一行展示切片,返回一整个片段,而非单项的一种通用的索引形式。考虑切片大概最好的方式是:它是一种解析(分析结果),特别当应用于字符串时 —— 它允许一步提取整个片段(子字符串)。切片可以被用来提取数据列,切掉前导和尾随文本等等。事实上,本章稍后将在文本解析的背景下探索切片。
切片的基础很简单易懂。当使用分号分隔开的偏移量对来索引序列对象如字符串时,Python 返回一个新对象,它包含由偏移量对标识的连续区间。左边的偏移被当做下界(包含),右边的是上界(不包含)。也就是说,Python 获取了从下界到上界(但不包括上界)的所有项,并返回包含获取到项的新对象。如果都省略,左边和右边界分别默认为 0 和正在切片对象的长度。
比如,在刚看到的例子中,S [1:3] 提取了偏移量 1 和 2 的项:它抓取第 2 和 3 项,然后在偏移量 3 的第 4 项前停下。接下来,S [1 获得了第一项后的所有项 —— 这里上界没有被指定,默认为字符串长度。最后,S [:-1] 获取了除了最后一项的所有项 —— 下界默认为 0,-1 指的是最后一项(不包含)。
这可能咋一看起来有点困惑,但一旦熟悉了后,索引和切片就是简单强大的工具。记住,如果不确定切片的效果,交互式地尝试一下。在下一章中,将看到通过赋给一个切片去一次性改变另一个对象的一整段连续区间是可能的(虽然对不可变对象如字符串不能这样)。下面是细节总结以供参考:
在偏移量索引(S [i])获取组成部分:
- 第一项在偏移量 0 处。
- 负索引意味着从后面或右边往回数。
- S [0] 获取第一项。
- S [-2] 获取从末尾开始的第二项(像
S[len(S)-2]
)
切片(S [i:j])提取序列的连续区间:
- 上界是不包含的。
- 如果被省略,切片边界值默认为 0 和序列长度。
- S [1:3] 获取从偏移量 1 到 3(但不包含 3)的项。
- S[1
获取才能从偏移量 1 到末尾(序列长度)的项。
- S [:3] 获取从偏移量 0 到 3(但不包含 3)的项。
- S [:-1] 获取从偏移量 0 到最后一项(但不包含最后一项)的项。
- S [:] 获取从偏移量 0 到末尾的所有项(创建 S 的一个顶层拷贝)。
* 高级切片(S [i:j:k])接收一个 step(步长)或(stride,也是步长之意)k
,它默认为 +1
:
- 允许跳过项并逆序 —— 见下一节。
这里列出的倒数第二个列表项被证明是一个很常见的技术:它创建了一个序列对象的完整顶层拷贝 —— 一个有相同值但不同内存区块的对象(将在第 9 章发现关于拷贝的更多知识)。这个技术对不可变对象如字符串不是很有用,但对那些可以就地更改的对象(如列表)特别有用。
在下一章中,将发现用来按偏移量(方括号)索引的语法也用来按键索引字典;操作看起来一样但解释起来不同。
” 对那些可以就地更改的对象(如列表)特别有用。“#
比如,下面是一个代码示例说明:
# create a list and assign it to variable 'my_list'
my_list = [1, 2, 3]
# create a copy of the list using the slice operator
my_list_copy = my_list[:]
# modify the copied list
my_list_copy.append(4)
# print the original list and the copied list
print("Original List:", my_list) # Original List: [1, 2, 3]
print("Copied List:", my_list_copy) #Copied List: [1, 2, 3, 4]
这显示了对列表进行拷贝的作用,可以修改拷贝而不会影响原列表。
推荐文章: