Effective Python 第11、12条:序列切片操作详解

python对序列做切割,如list、str、bytes等。其实,凡是实现了__getitem____setitem__这个两个魔法方法的类都可以切割(后面会介绍)。序列的切割是通过序列的下标来进行切割,序列的下标从0开始,且可以是负数,如从后数,倒数第一个下标也可以是-1。

1.基本用法

基本写法somelist[start:end]
表示从start开始一直取到end这个位置,但是不包括end位置本身的元素。且切片切出来的序列是一个新的序列,不会影响到原来的序列内容。

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[3:5])  # ['d', 'e']
print(a_list[1:7])  # ['b', 'c', 'd', 'e', 'f', 'g']

如果是从头开始切,就可以省略冒号左边的下标0,如果一直取到末尾,就可以省略右侧的下标。如下:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[:3])  # ['a', 'b', 'c']
print(a_list[5:])  # ['f', 'g', 'h']

使用负数作为下标,表示从列表的末尾开始往前数第几个元素。如下:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[-3:])  # ['f', 'g', 'h']
print(a_list[5:-2])  # ['f']

通过切片还可以实现列表复制

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
b_list = a_list[:]
print(b_list)
# ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

2.切片索引越界

当我们使用切片操作时,如果索引越界:起点与终点的位置超出了列表本身的边界,那么系统会自动忽略不存在的元素。例如:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[:10])  # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[-10:])  # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

但是当我们用下标直接访问列表时,索引越界就会抛出异常。如下:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[10])
# IndexError: list index out of range

3.使用切片修改序列内容

切片操作可以出现在赋值符号左侧,表示用右侧的那些元素代替列表中切片内的元素。而且赋值符号两边个数元素不必相等。位于切片范围之外的元素保留,但是列表长度可能发生变化。
例子如下:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
a_list[2:7] = [1, 2, 3]
print(a_list)  # ['a', 'b', 1, 2, 3, 'h']

下面例子会使列表边长:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
a_list[2:3] = [1, 2, 3]
print(a_list)  # ['a', 'b', 1, 2, 3, 'd', 'e', 'f', 'g', 'h']

4.带步进切片

写法:somelist[start:end:step]
step表示切片的间隔,也就是从start开始取第一个元素,向后数,每隔step个元素,取下一个元素,直到end(不包含end)为止。例如:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[::2])  # ['a', 'c', 'e', 'g']
print(a_list[1:7:3])  # ['b', 'e']

步进step还可以是负数,表示从start开始取第一个元素,向前数,每隔step的绝对值个元素,取下一个元素,直到end(不包含end)为止。注意,如果start比end小,则取出来的就是空。如下:

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[::-2])  # ['a', 'c', 'e', 'g']
print(a_list[7:1:-3])  # ['b', 'e']
print(a_list[1:7:-1])  # []

利用负步进值可以实现序列反转

a_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print(a_list[::-1])
# ['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

str = "人生苦短,我学python"
print(str[::-1])
# nohtyp学我,短苦生人

建议:
实际应用中,尽量不要同时使用起止下标和步进值;
如果必须使用,尽量使用正的步进值;
除了-1外,尽量不要使用其他负数做步进值,否则代码会很难懂。

要点

  1. 切片尽量简单,如果从头开始,就省略起始下标0,如果选取序列到末尾,省略终止下标;
  2. 切片允许下标越界,不用担心序列长度不够;
  3. 切片在赋值符号左边可以实现修改序列内容;
  4. 切片可以指定步进值,但是尽量不要使用太复杂的切片,见上面的建议。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan-running

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值