Python切片

文章目录

前言

提示:这里可以添加本文要记录的大概内容:

利用python解决问题的过程中,经常会遇到从某个对象中抽取部分值的情况。“切片”操作正是专门用于实现这一目标的有力武器。理论上,只要条件表达式得当,可以通过单次或多次切片操作实现任意目标值切取。
切片操作的基本语法比较简单,但如果不彻底搞清楚内在逻辑,也极容易产生错误,而且这种错误有时隐蔽得较深,难以察觉。
切片操作不会因为下标越界而抛出异常,而是简单地在列表尾部截断或者返回一个空列表,代码具有更强的健壮性。
切片是Python序列的重要操作之一,适用于列表、元组、字符串、range对象等类型。本节课以列表类型作为讲解的对象,其结论可推广至其他可切片对象。
可以使用切片来截取列表中的任何部分,得到一个新列表。

提示:以下是本篇文章正文内容,下面案例可供参考

一、切片操作

Python切片操作的一般方式:object[start_index:end_index:step]
一个完整的切片表达式包含两个":",用于分隔三个参数(start_index、end_index、step)。
第一个数字表示切片开始位置(默认为0)
第二个数字表示切片截止(但不包含)位置(默认为列表长度)
第三个数字表示切片的步长(默认为1),当步长省略时可以顺便省略最后一个冒号。

当只有一个":" 时,默认第三个参数step=1;例如:a[1:3]

当一个":"也没有时,表示切取start_index指定的那个元素。
相当于取指定位置的值。
例如:a[2]

Python切片操作的一般方式:

step:正负数均可,其绝对值大小决定了切取数据时的‘‘步长”,而正负号决定了“切取方向”,正表示“从左往右”取值,负表示“从右往左”取值。当step省略时,默认为1,即从左往右以步长1取值。

切取方向非常重要!

start_index:表示起始索引(包含该索引对应值);该参数省略时,表示从对象“端点”开始取值,至于是从“起点”还是从“终点”开始,则由step参数的正负决定,step为正从“起点”开始,为负从“终点”开始。

end_index:表示终止索引(不包含该索引对应值);该参数省略时,表示一直取到数据“端点”,至于是到“起点”还是到“终点”,同样由step参数的正负决定,step为正时直到“终点”,为负时直到“起点”。

切取单个元素

代码如下(示例):
首先,定义一个列表如下
>>>a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
当索引只有一个数时,表示切取某一个元素。

>>>a[0]
>>>0
>>>a[-4]
>>>6

注意:

虽然切片操作不会因为下标越界而抛出异常,但是切单个元素的情况需要注意,还是会报异常。

>>> a[-100]
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    a[-100]
IndexError: list index out of range

>>> a[0:100:1]                 #前100个元素,自动截断
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[100:]                    #下标100之后的所有元素,自动截断
[]

切取完整对象

正序

>>>a[:] #从左往右
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>>a[::]#从左往右
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

逆序

>>>a[::-1]#从右往左
>>> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

start_index和end_index全为正(+)索引的情况

>>>a[1:6]
>>>[1,2,3,4,5]

step = 1,从左往右取值,start_index = 1 到 end_index=6 同样表示从左往右取值

>>>a[1:6:-1]
>>>>[]

输出为空列表说明没有取到数据
step = -1,决定了从右往左取值,而start_index=1 到 end_index=6决定了从左往右取值
两者矛盾所以为空

>>>a[6:2]
>>>[]

同样输出为空列表
step=1,决定了从左往右取值
而start_index=6 到 end_index=2 决定了从右往左取值,两者矛盾所以为空

>>>a[:6]
>>>[0,1,2,3,4,5]

step=1,表示从左往右取值,而 start_index 省略时,表示从端点开始,
因此这里的端点是 “起点”,即从 “起点” 值 0 开始一直取到 end_index=6 (该点不包括)

>>>a[6:]
>>>[6,7,8,9]

step = 1,从左往右取值,从 start_index=6开始,一直取到 “终点” 值9

>>>a[6::-1]
>>>[6,5,4,3,2,1,0]

step=1,从右往左取值,从start_index=6开始,一直取到 “起点” 值0

start_index和end_index全为负(-)索引的情况

>>>a[-1:6]
>>>[]

step=1,从左往右取值,而start_index= -1 到 end_index= -6 决定了从右往左取值
两者矛盾,所以为空
索引 -1 在 -6 右边

>>>a[-1:-6:-1]
>>>[9,8,7,6,5]

step = -1,从右往左取值,start_index = -1 到 end_index = -6 同样是从右往左取值
索引 -1 在 6 右边

>>>a[-6:-1]
>>>[4,5,6,7,8]

step=1,从左往右取值,而start_index = -6 到 end_index = -1 同样是从左往右取值
索引 -6 在 -1 左边

>>>a[:-6]
>>>[0,1,2,3]

step=1,从左往右取值,从"起点" 开始一直取到 end_index = -6 (该点不包括)

>>>a[:-6:-1]
>>>[9,8,7,6,5]

step = -1,从右往左取值,从"终点" 开始一直取到 end_index = -6 (该点不包括)

>>>a[-6:]
>>>[4,5,6,7,8,9]

step=1,从左往右取值,从start_index = -6 开始,一直取到 " 终点"

>>>a[-6::-1]
>>>[4,3,2,1,0]

step = -1,从右往左取值,从start_index = -6 开始,一直取到 “起点”

start_index和end_index正(+)负(-)混合索引的情况

>>>a[1:6]
>>>[1,2,3]

start_index=1 在 end_index = -6 左边,因此从左往右取值
step=1 同样决定了从左往右取值,因此结果正确

>>>a[1:-6:-1]
>>>[]

start_index=1 在 end_index = -6 的左边,因此从左往右取值,但step = -1 则决定;从右往左取值。
两者矛盾,因此为空

>>>a[-1:6]
>>>[]

start_index = -1 在 end_index=6 的右边,因此从右往左取值
但step=1 则决定了从左往右取值,两者矛盾,因此为空

>>>a[-1:6:-1]
>>>[9,8,7]

start_index= -1 在 end_index=6 的右边,因此从右往左取值,而step = -1
同样决定了从右往左取值,因此结果正确

多层切片操作

>>>a[:8][2:5][-1:]
>>> [4]

相当于:

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

理论上可无限次多层切片操作,只要上一次返回的是非空可切片对象即可。

切片操作的三个参数可以用表达式

>>>a[2+1:3*2:7%3]
>>> [3, 4, 5]

即:a[2+1:3*2:7%3] = a[3:6:1]

二、Python切片一些常用操作

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

取偶数位置

>>>b = a[::2]
[0, 2, 4, 6, 8]

取奇数位置

>>>b = a[1::2]
[1, 3, 5, 7, 9]

拷贝整个对象

>>>b = a[:] 
>>> b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> id(a)
2670565854152
>>> id(b)
2670566271112

>>> c=a.copy()
>>> c
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> id(a)
2670565854152
>>> id(c)
2670565953416

需要注意的是:[:]和.copy()都属于“浅复制”,只复制最外层元素,内层嵌套元素则通过引用方式共享,而非独立分配内存

所谓浅复制,是指生成一个新的列表,并且把原列表中所有元素的引用都复制到新列表中。如果原列表中只包含整数、实数、复数等基本类型或元组、字符串这样的不可变类型的数据,一般是没有问题的。如果原列表中包含列表之类的可变数据类型,由于浅复制时只是把子列表的引用复制到新列表中,这样的话修改任何一个都会影响另外一个。
只拷贝最外层元素,内层嵌套元素则通过引用方式共享,而非独立分配内存。

如果要 “深复制” 该如何写?

>>> import copy                    # 引入 copy 库
>>> a = [3, 5, 7,['x', 'y']]
>>> b = copy.deepcopy(a)           # 调用 copy 库中的 deepcopy 函数
>>> a  
[3, 5, 7, ['x', 'y']]
>>> b
[3, 5, 7, ['x', 'y']]
>>> a[3][1] = 'abc'
>>> a
[3, 5, 7, ['x', 'abc']]  
>>> b                       # 这下怎么折腾都不会影响到 b 了
[3, 5, 7, ['x', 'y']]

三、使用切片来原地修改列表内容

增加和修改列表元素列表元素

>>> aList = [3, 5, 7]
>>> aList[len(aList):] = [9]    #在尾部追加元素
>>> aList
[3, 5, 7, 9]
>>> aList[:3] = [1, 2, 3]       #替换前3个元素
>>> aList
[1, 2, 3, 9]
>>> aList[:3] = []              #通过修改的方式删除前3个元素
>>> aList
[9]
>>> aList = list(range(10))
>>> aList
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> aList[::2] = [0]*5         #替换偶数位置上的元素
>>> aList
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]
>>> aList[::2] = [0]*3        #切片不连续,两个元素个数必须一样多
ValueError: attempt to assign sequence of size 3 to extended slice of size 5

使用del与切片结合来删除列表元素

>>> aList = [3,5,7,9,11]
>>> del aList[:3]                 #删除前3个元素
>>> aList
[9, 11]

>>> aList = [3,5,7,9,11]
>>> del aList[::2]               #删除偶数位置上的元素
>>> aList
[5, 9]

使用列表对象的sort方法进行原地排序,支持多种不同的排序方法

>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> import random
>>> random.shuffle(aList)
>>> aList
[3, 4, 15, 11, 9, 17, 13, 6, 7, 5]
>>> aList.sort()                             #默认是升序排序
>>> aList.sort(reverse = True)               #降序排序
>>> aList
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
>>> aList.sort(key = lambda x:len(str(x)))      #按转换成字符串的长度排序
>>> aList
[9, 7, 6, 5, 4, 3, 17, 15, 13, 11]

使用内置函数sorted()对列表进行排序并返回新列表

>>> aList
[9, 7, 6, 5, 4, 3, 17, 15, 13, 11]
>>> sorted(aList)                            #升序排序
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> sorted(aList,reverse = True)             #降序排序
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]

与sort()区别是,sorted()返回一个新列表,并不对原列表进行任何修改。

使用列表对象的reverse方法将元素原地逆序

>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList.reverse()
>>> aList
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]

四、总结

切片概念和一般操作

1、切取单个元素
2、切取完整对象
3、start index 和 lend index 全为正(+)索引的情况
4、start index 和 lend index 全为负(-)索引的情况
5、start index 和 end index 正(+)负(-)混合索引的情况
6、多层切片操作
7、切片操作的三个参数可以用表达式
8、其他对象的切片操作

切片常用操作

1、取偶数位置
2、取奇数位置
3、拷贝整个对象,浅复制和深复制
4、使用切片来原地修改列表内容
5、列表排序
正序、倒序

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年3月5日 上午9:52
下一篇 2023年3月5日 上午9:53

相关推荐