Python:切片操作详解

基本语法:

object[start:end:step=1]
  1. step:正负数均可,其绝对值大小决定了切取数据时的‘‘步长”,而正负号决定了“切取方向”,正表示“从左往右”取值,负表示“从右往左”取值。当step省略时,默认为1,即从左往右以步长1取值。
  2. start:开始位置索引。
  3. end:结束位置索引。

功效:从 start 到 end 按照 step 选取元素作为一个新的对象。(包括 start,不包括 end)

如果只出现出现一个冒号:则为第一个冒号。

Note: 最重要的是 step 操作,它不仅决定了切片的步长,还决定了切片的方向。更进一步的是还会影响 start 和 end 的默认取值。

理解精髓

- step 为正数:切片方向从左到右,start 默认为 0(即为最左边位置索引), end 默认为 length(对象长度,即为最右边位置索引的下一位,(因为取不到 end))。
- step 为负数:切片方向从右到左,start 默认为 length-1(对象长度减一,即为最右边位置索引), end 默认为 -1(即为最左边位置索引的前一位(因为取不到 end))

浅拷贝 or 深拷贝?

a_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

b_list = a_list[0:5]

print('Id of a_list:', id(a_list))
print('Id of a_list:', id(b_list))

for i in a_list:
    print('%s-th element in a_list: %s' % (i+1, id(i)))

print('*********')

for i in b_list:
    print('%s-th element in b_list: %s' % (i+1, id(i)))

结果如下:
在这里插入图片描述
了解浅拷贝的都知道,这是一种典型的浅拷贝方式!再用一个例子证明:

a_list = [0, 1, [2, 3, 4]]

b_list = a_list[0:3]

b_list[-1][0] = 20

print(a_list)

结果如下:
在这里插入图片描述
修改浅拷贝对象中的可变对象元素相互影响。这就是浅拷贝的注意事项啊。如果不了解浅拷贝,可以参考:Python:赋值,浅拷贝(copy)和深拷贝(deepcopy)

3. 例子:

3.1 a[:] and a[::]

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(a[:])
print(a[::])

在这里插入图片描述
理解:step 默认为 1, 正数,方向从左到右,start 和 end 分别为最左边和最右边索引的下一位(取不到 end)。

3.2 超出索引会如何?

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(a[0:100])

在这里插入图片描述
不会报错!

3.3 step 大于 0

Note: 我们始终把握我们理解的精髓:step 大于 0,切片方向从左到右,start 默认最左边位置,end 默认最右边位置的下一个位置(因为取不到 end)。记住这个,下面的所有情况就很好理解了。

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print('a[1:6]:', a[1:6])
print('a[6:2]:', a[6:2])
print('a[:6]:', a[:6])
print('a[6:]:', a[6:])
print('a[-1:-6]:', a[-1:-6])
print('a[-6:-1]:', a[-6:-1])
print('a[:-6]:', a[:-6])
print('a[-6:]', a[-6:])
print('a[1:-6]', a[1:-6])
print('a[-1:6]', a[-1:6])

在这里插入图片描述
a[1:6]:没啥好说的,1 索引到 6 索引,但是不包括 6 索引;
a[6:2]:切片方向为左到右,从 6 索引切到 2 索引,不包括 2 索引。因此这样切不出来,即为空列表;
a[:6]:step 为正,start 默认为 0,因此等价于 a[0:6];
a[6:]:step 为正,end 默认为 10(length,最右边位置的下一位), 等价于 a[6:10];
a[-1:-6]: step 为正,因此这样切不出来,即为空列表;
a[-6:-1]:step 为正,从倒数第 6 个到倒数第 1 个,取不到倒数第 1 个;
a[:-6]:step 为正,start 默认为 0,因此是去 0 索引到倒数第 6 个,不包括倒数第 6 个;
a[-6:]:step 为正,end 默认为 10(length,最右边位置的下一位),因此为倒数第 6 个之后的所用元素;
a[1:-6]:step 为正,从 1 索引到倒数第 6 个,不包括倒数第 6 个;
a[-1:6]:step 为正,从倒数第一个从左往右切到 6 索引,不包括 6 索引,切不出来,即为空列表。
Note: 负索引代表倒数第几个元素,例如 a[-1] 即为最后第一个元素,a[-6] 即为最后第六个元素。

3.3 step 小于 0

Note: 我们始终把握我们理解的精髓:step 小于 0,切片方向从右到左,start 默认为 length-1(对象长度减一,即为最右边位置索引), end 默认为 -1(即为最左边位置索引的前一位(因为取不到 end))。记住这个,下面的所有情况就很好理解了。

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print('a[1:6:-1]:', a[1:6:-1])
print('a[:6:-1]:', a[:6:-1])
print('a[6::-1]:', a[6::-1])
print('a[-1:-6:-1]:', a[-1:-6:-1])
print('a[:-6:-1]:', a[:-6:-1])
print('a[-6::-1]:', a[-6::-1])
print('a[1:-6:-1]:', a[1:-6:-1])
print('a[-1:6:-1]', a[-1:6:-1])

在这里插入图片描述
a[1:6:-1]:从右到左切 1 索引到 6 索引,不包括 6 索引,切不出来,所以为空;
a[:6:-1]:step 为负,start 默认为 9 (length - 1),因此是取最后 1 个到 6 索引,不包括 6 索引;
a[6::-1]:step 为负,end 默认为 -1,因此从右往左取 6 索引到 -1 索引,不包括 -1 索引。
a[-1:-6:-1]:step 为负,从右到左去倒数第 1 个到倒数第 6 个,不包括倒数第 6 个。
a[:-6:-1]:step 为负,start 默认为 9 (length - 1),从右到左取倒数第 1 个到倒数第 6 个,不包括倒数第 6 个,等价于上一个。
a[-6::-1]:step 为负,end 默认为 -1,从右到左取倒数第 6 个之前的所有。
a[1:-6:-1]:step 为负,从右到左去倒数第 6 个到倒数第 1 个,不包括倒数第一个,取不出来,所以为空列表。
a[-1:6:-1]:step 为负,从右到左去倒数第 1 个到 6 索引,不包括 6 索引。

总结:把握精髓,step 不仅决定切片方向,还会影响 start 和 end 的默认取值。

4. 常见应用:

4.1 取偶数索引位置:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(a[::2])

在这里插入图片描述

4.2 取奇数索引位置:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(a[1::2])

在这里插入图片描述

4.3 插入元素:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a[1:1] = [100]
print(a)

在这里插入图片描述
注意我们切出来的是一个 list,所以赋值为 [100]。
这里可能和浅拷贝的理解有偏差:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = a[:]
b[1] = 100
print(a)

在这里插入图片描述
这样符合浅拷贝的理解:修改的是不可变对象,因此相互之间不影响。
但是上一种情况是由于没有赋值给一个新的变量,而是在原来变量上面操作的。

4.3 少修改多元素/多修改少元素:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a[1:1] = [100, 200]
print(a)

多修改少,可以看到 a 变长了。

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a[1:5] = [100, 200]
print(a)

少修改多,可以看到 a 变短了。

5. 其他

可以切片的还包括字符串(str)和元素(tuple)等,不过原理都是一样的,这里不再赘述。

END

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值