Python 切片

切片就是在有序序列对象字符串元组列表)中选择某个范围内的项。 切片可被用作表达式以及赋值 del 语句的目标。

Python的有序序列对象可以用索引号来引用的元素的,索引号可以是正数由0开始从左向右,也可以是负数由-1开始从右向左。

以 a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 为例:

需注意的是有序序列对象某个索引位置返回的是一个元素,而切片操作返回是和被切片对象相同类型对象的副本切片的返回结果是一个新的独立的序列。以列表为例,列表切片后得到的还是一个新的列表,占用新的内存地址。② 切片是取操作,不改变原值。③ 切片的返回结果类型和切片对象类型一致,返回的是切片对象的子序列。如:对一个列表切片返回一个列表;字符串切片返回字符串。【如果被切片的对象是可变的序列对象,并且切片表达式在等号 = 的左侧,就可以直接更改原可变序列对象的值。如果切片表达式在等号 = 的右侧,那么返回的就是新的独立的序列对象副本被切片对象是不可变的序列对象只能处于等号= 的右侧返回被切片对象的子序列副本。】

被切片对象不是可变对象,拷贝的是值;被切片对象是可变对象,是该可变元素的引用,共用一个空间。对于列表切片只是浅拷贝,它拷贝的是原列表中的引用。④ 切片生成的子序列元素是源版的拷贝,因此切片是一种浅拷贝。

切片操作的基本表达式:

object[start_index:end_index:step]
  1. start:切片的起始位置,如果没有值的话从头开始。
  2. end:切片的结束位置,但不包含end(前闭后开),如果没有值的话表示切割到结束为止。
  3. step:步长,默认取值为1,如果步长为正数的情况表示从左往右,反正若为负数则表示从右往左。step 的正负决定切的方向,这一点需要尤为注意!!!

注意:这些值都可以大于列表的长度,不会报越界。但是会发生截断,就是仍然按照范围查找,但是超出序列数据范围部分,全部被遐想成空值,最终获取到空值进行忽略即可。

被切片序列返回的子序列长度 count = end - start

切片并非列表的专属操作,但是因为列表最具代表性,下面主要以列表来举例。

均以列表 >>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 为例。

切割(取)完整对象:

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[:] ## 单独一个冒号,代表从头取到尾,步长默认为1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[::] ## 单独两个冒号一样代表从头取到尾,步长默认为1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[::-1]##注意,两个冒号后面是步长,步长为1,故应从右往左取
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

切片中的三个参数为表达式:

>>> a 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> a[1+2:2*3:7%2]  ## 思路一样,运算出来,继续切
[3, 4, 5] 

取偶数位置:

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

取奇数位置:

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

切取单个值:

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

修改单个元素:(是切片的应用吗?)

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

替换一部分元素:(是原先的 a 吗?)

>>>a[3:6] = ['A','B']            # [3:6]==[3,4,5],所以将3-5的索引的值替换成A、B
[0, 1, 2, 'A', 'B', 6, 7, 8, 9]

在某个位置插上元素:

>>>a[3:3] = ['A','B','C']                # [3:3] == [] ,所以在3之前直接插入数值
[0, 1, 2, 'A', 'B', 'C', 3, 4, 5, 6, 7, 8, 9]    
>>>a[0:0] = ['A','B']                    # 同理,在0之前插入数值
['A', 'B', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

拷贝整个对象:

>>>b = a[:] 
>>>print(b)        # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>print(id(a))    # 41946376
>>>print(id(b))    # 41921864

>>>b = a.copy()
>>>print(b)        # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>print(id(a))    # 39783752
>>>print(id(b))    # 39759176

需要注意的是:[:]和.copy()都属于“浅拷贝”,只拷贝最外层元素,内层嵌套元素则通过引用,而不是独立分配内存。

>>>a = [1,2,['A','B']]
>>>print('a={}'.format(a))
a=[1, 2, ['A', 'B']]      # 原始a

>>>b = a[:]
>>>b[0] = 9           # 修改b的最外层元素,将1变成9
>>>b[2][0] = 'D'       # 修改b的内嵌层元素
>>>print('a={}'.format(a))  # b修改内部元素A为D后,a中的A也变成了D,说明共享内部嵌套元素,但外部元素1没变。
a=[1, 2, ['D', 'B']] 

>>>print('b={}'.format(b))  # 修改后的b
b=[9, 2, ['D', 'B']] 

>>>print('id(a)={}'.format(id(a)))
id(a)=38669128

>>>print('id(b)={}'.format(id(b)))
id(b)=38669192

连续切片操作:

>>>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  # [-1:] = [-1] 即:取最后一个值

理论上可无限次连续切片操作,只要上一次返回的依然是非空可切片对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值