一文带你搞明白Python切片操作

作为一个学完Python基础知识的测试,终于可以像RD们自己写脚本处理任何场景吧,如何优雅地写出来代码,接下来开启进阶版的Python。

1. 前言

在刚学python时候,我们都知道字符串(String)、列表(list)和元组(tuple)序列化数据类型支持切片操作。

# slice operation
TUPLE = (1,2,3,4)
LIST = [1,2,3,4]
STRING = "1234"

print("TUPLE[1:3]:",TUPLE[1:3])
print("LIST[1:3]:",LIST[1:3])
print("STRING[1:3]:",STRING[1:3])

# output
TUPLE[1:3]: (2, 3)
LIST[1:3]: [2, 3]
STRING[1:3]: 23

通过上述例子,我们可以快速使用“区间”的方式截取到想要的数据。那么最后一位始终都没有取到?接下来,我们对熟悉的切片操作进行系统学习。

2. 什么是切片?

2.1 切片概述

Python 序列数据类型索引从左到右开始是从0开始,依次加+1;诺从右到左索引从-1开始,依次加-1。

在Python 中访问子序列/字符串,使用方括号[]来截取指定的子序列/字符串。例如在列表中要元素2和3,则切片截取为LIST[1:3]

2.2 忽略最后一位元素

在Python中,进行切片操作会不包含最后一位元素,这一风格是与C语言等语言保存以索引位置从0开始的做法。

切片忽略最后一位元素会有以下好处:

  • 当切片操作只给出最后一位时,可以直接明了看到截取的子序列的长度。例如LIST[:2]中包含两个元素

  • 根据 Edsger W. Dijkstar 解释,索引位置从0开始比从1开始优势,元素的序数(下标)等于序列中它之前的元素数。切片长度计算方式可以直接(stop-start)计算出

  • 同时,指定任何一个索引位置x,可以对序列切割成不重叠的两个子序列LIST[:x]和LIST[x:]。

 >>> LIST = [1,2,3,4] 
>>> LIST[:2] # 直接可以知道截取子序列为2
[1, 2]
>>> LIST[2:] # 将LIST在索引位置2处切片
[3, 4]
>>> 

3. 切片原理

切片操作是使用方括号 [] 进行运算的。其格式为 [start:stop:step]。对象在start和stop区间中取出间隔step的元素。step可以取负数。

>>> LIST[1:4:2] 
[2, 4]
>>> LIST[-1:-4:-1] 
[4, 3, 2]
>>> LIST[::-1] 
[4, 3, 2, 1]
>>> LIST[::-2] 
[4, 2]
>>>

start:stop:step 形式在方括号[]内,使用索引下标计算后,返回一个切片对象:slice(start,stop,step)

当序列进行seq[start:stop:step]分片计算时,Python会调用seq.getitem(slice(start,stop,step))方法以元组的形式接收[]方括号索引。

查看Python内置 slice() 方法属性,有三个start、stop和step数据属性和indices方法

>>> slice  
<class 'slice'>
>>> dir(slice) 
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__',
 '__hash__', '__init__', '__init_subclass__', '__le__', 
 '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', 
 '__repr__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__', 'indices', 'start', 'step', 'stop']
>>>

根据当序列调用slice方法后,会先执行Seq.indices(len)方法计算出序列Seq从开始start和结束stop位置,步数step。当超出边界时,会截掉。

>>> slice(None,5,1).indices(2) #1
(0, 2, 1)
>>> slice(-3,None,None).indices(2) #2
(0, 2, 1)
>>>

#1 seq[:5:1] 等于 seq[0:2:1]

#2 seq[-3:] 等于 seq[0:2:1]

切片其实还可以支持使用逗号分开多个索引,例如第三库Numpy库就是使用这个特性。

4. 切片赋值

将序列进行切片操作后得到切片对象可以进行赋值,但是必须遵循以下条件:

  • 切片做为对象,那么等号右边必须是一个可迭代的对象

  • 即使切片里只有一个值,也要转换成可迭代的序列

  • 否则的话,系统会抛出TypeError

>>> LIST = [1,2,3,4,5]
>>> LIST[1:4] = 23
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>>

5. 切片计算

在Python中,切片对象可以进行 “+”或“*”运算,以达到拼接组合成新的切片对象。

  • 通过 “+” 连接的是两个同类型序列,两个序列拼接后序列不会发生改变,Python内部会重新创建新的序列
>>> LIST = [1,2,3,4]
>>> LIST2 = [5,6,7]
>>> LIST + LIST2
[1, 2, 3, 4, 5, 6, 7]
>>> s1 = "Jue"    
>>> s2 = "Jin" 
>>> s1 + s2
'JueJin'

  • 通过“Seq*n”,可以将原数据类型复制n份,然后再拼接起来组合新的序列
>>> LIST = [1,2,3,4]
>>> LIST * 3
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
>>> s1 = "Jue"       
>>> s1 * 3
'JueJueJue'

以上案例中,都是针对元素是不可变的数据类型进行复制操作的,那么元素是可变数据类型进行复制会发生什么样呢?

例如我们要创建一个二维的列表,长度为3。可能快捷的写法如下:

>>> LIST = [["_"]]*3 
>>> LIST
[['_'], ['_'], ['_']]

但是对坐标0,0进行赋值,发现3个元素都发生变化

>>> LIST[0][0] = 1
>>> LIST
[[1], [1], [1]]

这个和我们实际想要的效果不一样,我们需要得到是列表中每一个元素之间都是独立的,那么我们写法上要与上述有区别的

>>> LIST = [["_"] for i in range(3)] 
>>> LIST
[['_'], ['_'], ['_']]
>>> LIST[0][0] = 1
>>> LIST
[[1], ['_'], ['_']]
>>>

为什么两种写法差距这么大,原因在于第一种写法虽然看上去和写法二一样,但是写法一初始化时候,是得到元素都是引用,都指向同一个列表。当我们对其中一个元素进行赋值时,另外两个也会跟着变化。

6. 总结

本期,对 Python 关于序列、字符串常用到的切片操作,进行深入学习。切片操作原理在于Python内部会通过__getitem__()方法调用slice对象,然后slice对象通过indices(len)方法算出切片的长度。哪怕遇到缺失索引和负数索引,以及长度超过目标序列的切片都可以优雅地进行处理。

---------------------------END---------------------------

题外话

在这里插入图片描述

感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。

👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

六、面试宝典

在这里插入图片描述

👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)

若有侵权,请联系删除

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值