首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一文理清Python列表切片的操作细节

大家好,欢迎来到 Crossin的编程教室 !

有人说:列表绝对是python中最常用的数据结构,没有之一!

本文我们就来关注列表中的一个重要操作:切片。给大家理一理其中的技术细节。

内容不多,5分钟足矣,但对于大多数pythoners相信会有收获。

切片热身

列表的切片操作是指对其中单个或者多个索引对应元素进行的操作,具有如下几个特点:

切片区间是左闭右开区间

切片的下标可以是负数,当为负数时,意味着从后到前的位置,且-1位倒数第一个

默认步长是1,可通过增加第三个参数实现不同切片

步长是-1时,可实现倒序切片

下标缺省时,表示从最"前"到最"后"(这里的前后要结合上下文来看,具体后面有示例)

例如,下面这些常规操作大家应该都很熟悉:

这里重点补充对于缺省下标的理解,即列表内部是以什么原则处理缺省下标值:

总结来说,就是步长为正数时,首末缺省下标分别是0和n;步长为负时,首末缺省下标分别是-1和-n-1。特别地,当步长为-1、首末下标均缺省时,效果等价于lyst.reverse()或者reversed(lyst),但具体功能有区别:

另外,列表中切片索引数值要求均为整数(曾有PEP提议,索引可接受任意值,然后由python进行隐式取整处理,但被reject了),且步长索引不能为0

切片访问

对列表某索引对应值进行访问,当对单个索引访问时,要注意索引的合格范围;但对列表切片时则不会显式报错。其中,单索引的合格范围为-n—n-1,共2n个合格索引,其中n为列表长度;而对于范围索引时,即使访问越界也不会显式报错,而仅仅是返回结果为空:

这里补充一个亲身经历的错误:要倒序返回一个列表的前n-1个值(即最后一个元素除外的所有元素倒序输出),因为可以正负索引混合使用,所以自己想当然的写下了如下语句:

我的逻辑是倒数第二个索引是-2,返回前面的所有值,第一个值是下标0,但由于索引是左开右闭区间,所以如果写0的话访问不到,那么要比0再小一个,也就是-1。但实际上,python可不这么想,它会将索引-2解释为倒数第二个值没错,但是索引-1会解释成倒数第一个值(更准确的讲,是取不到这个值),所以上面的返回结果为空,无论步长是正还是负!

当然,实现这一需求的方法很多,只要理解了切片的索引原则:

切片赋值

前面提到,列表的单索引越界访问会报错,切片访问不报错但返回结果为空。这一逻辑也类似于列表的赋值操作:对于单索引的赋值,要求索引必须在合格范围之内,否则报错;但对于切片的赋值则"无需"考虑索引是否合法,甚至无需考虑赋值长度是否匹配

实际上,由于对超出列表长度的索引位置进行切片赋值会直接拼接,所以这个操作相当于列表的extend():

既然提到了列表的extend()操作,那么下面的insert()操作不仅不会报错,而且实际上相当于执行了append()操作:

切片拷贝

由于参数引用的特殊性,python中的赋值操作或许曾令人抓狂其中而不得自拔,个人也不敢说完全理解其中的原理,所以这一部分权当是抛砖引玉。

正因为python中拷贝的特殊性,所以有个专门的库叫copy,里面有2个重要的方法分别是copy.copy()和copy.deepcopy(),顾名思义,后者叫做深拷贝,前者自然就叫做浅拷贝。当然,这里不打算介绍这个库和相应方法,而只是想就此引出列表中如何通过切片实现拷贝。

如果想要对一个列表进行拷贝,且后续操作互不干扰,那么简单的直接赋值是不能完成任务的,例如执行以下语句,a和b其实管理和引用的是同一块内存,所以操作是同步的,未实现真正的拷贝:

如果想要实现a、b从此毫无瓜葛,那么简单的拷贝实现有两种:

另外,再体会下这3个例子:

复制列表,改某个值其他不会受到影响

嵌套复制列表,牵一发动全身

推导式+复制生成嵌套列表,改1个值其他不受影响

不得不说,python里面的变量赋值与引用确实有些难以理解,这个只能靠不断积累和尝试,得细品!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210319A05LBG00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券