本文来自异想之旅公开发布的Python教程,原文地址:https://www.yuque.com/yxzl/python
本文以列表举例,字符串与之类似,将在最后简单对比。
我们经过 1.6 章节的学习已经知道,我们定义一个列表 a = [1, 2, 3]
,可以通过 a[0]
a[1]
a[2]
的方式取出其中的每一项。
这就是最简单的索引,现在在这个的基础上,我们再介绍一个负数索引。
我们定义这样的一个列表,并尝试打印它的每一项:
t = ['a', 'b', 'c', 'd', 'e']
print(t[0], t[1], t[2], t[3], t[4]) # a b c d e
print(t[-1], t[-2], t[-3], t[-4], t[-5]) # e d c b a
可以看到, 0,1,2...
分别取出了列表从前往后数的第 1,2,3...
项,而 -1,-2,-3...
分别取出了列表从后往前数的第 1,2,3...
项。
为什么第1
项索引为0
?因为编程语言从0
开始计数。为什么倒数第一项索引为-1
而不是-0
?因为-0
和0
相同,将导致冲突。
下面再用这张比较直观的图片帮助大家记忆索引。
我们先看如下的示例:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[0:3]) # 第一项:第四项
print(a[3:6]) # 第四项:第七项
print(a[2:7]) # 第三项:第八项
为了在前期帮助大家排除索引从 0 开始计数的干扰,我用注释标出来了每个索引对应在列表中是第几项。转换完后,第几项就是数字几,不晕了吧~
输出内容如下:
[1, 2, 3]
[4, 5, 6]
[3, 4, 5, 6, 7]
我们分析一下结果(不要搞错索引和第 x 项):
0:3
时,输出的是原列表索引为 0
到 2
的片段3:6
时,输出的是原列表索引为 4
到 6
的片段2:7
时,输出的是原列表索引为 2
到 6
的片段a:b
时,输出的是原列表索引为 a
到 b - 1
的片段为什么是 b - 1
呢?这就要提到编程中的第二个重要法则(上一个是从零开始计数):左闭右开。即我们传入 a:b
时,实际上取到的区间为
[
a
,
b
)
[a,b)
[a,b) 这样的左闭右开区间。实在不理解的话,就请先记住吧。
如果在 a:b
中我们缺失了一个参数,Python 会默认截取到字符串的开头或结尾:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[:3]) # 到索引为3-1=2的位置结束,输出:[1, 2, 3]
print(a[6:]) # 从索引为6的位置开始,输出:[7, 8, 9]
自然,我们也可以使用负数索引:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[-6:-4]) # 输出:[4, 5]
print(a[-3:]) # 输出:[7, 8, 9]
老规矩,先看程序:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[0:5:2]) # 输出:[1, 3, 5]
print(a[2:8:3]) # 输出:[3, 6]
当我们传入两个参数 a:b
时,取到的列表大概长这样:[(a), (a + 1), (a + 2), ..., (b - 2), (b - 1)]
((x)
表示列表索引为 x
的元素,下同)
如果传入 a:b:c
三个参数, a
与 b
控制开始和结束位置的功能不变,而 c
定义的是每取完一个元素后增加的步长。如当我们传入 0:5:2
时,取到的列表为 [(0), (2), (4)]
;当我们传入 2:8:3
时,取到的列表为 [(2), (5)]
当然,第三个参数 c
也可以是负数,具体实现如下:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[5:0:-2]) # 输出:[6, 4, 2]
print(a[::-2]) # 输出:[9, 7, 5, 3, 1]
print(a[::-1]) # 输出:[9, 8, 7, 6, 5, 4, 3, 2, 1]
你会发现,一维我们叫做索引,而二维、三维我们叫做切片,这是为什么?因为在只传递一个数字时,我们获取到的是一个元素;而在传递两个及以上的数字时,我们获取到的是原本的列表的一段子列表,哪怕这个列表的长度为一甚至是零。
与列表大同小异
a = 'HelloWorld'
print(a[0:5]) # Hello
print(a[6:8]) # or
print(a[0:8:2]) # Hloo
print(a[::-1]) # dlroWolleH