彻底理解Python list切片原理


Posted in Python onOctober 27, 2017

关于list的insert函数

list#insert(ind,value)在ind元素前面插入value

首先对ind进行预处理:如果ind<0,则ind+=len(a),这样一来ind就变成了正数下标

 预处理之后,

 当ind<0时,ind=0,相当于头部插入
 当ind>len(a)时,ind=len(a),相当于尾部插入

切片实例

Python中的列表切片非常灵活,要根据表象来分析它的内在机理,这样用起来才能溜。

下标可以为负数有利有弊,好处是使用起来更简便,坏处是当我下表越界了我也不知道反倒发生奇奇怪怪的错误。

print str[0:3] #截取第一位到第三位的字符
print str[:] #截取字符串的全部字符
print str[6:] #截取第七个字符到结尾
print str[:-3] #截取从头开始到倒数第三个字符之前
print str[2] #截取第三个字符
print str[-1] #截取倒数第一个字符
print str[::-1] #创造一个与原字符串顺序相反的字符串
print str[-3:-1] #截取倒数第三位与倒数第一位之前的字符
print str[-3:] #截取倒数第三位到结尾
print str[:-5:-3] #逆序截取

可见,列表的下标有三个参数:beg(起始下标),end(终止下标),delta(变化量)

  1. 当delta小于0时,beg默认为len(array)-1,end默认为开头之前。
  2. 当delta大于0时,beg默认为0,end默认为最末之后。
  3. 当delta未给出时:delta默认为1

这个代码示例演示了大概原理,学习一件事物,先学习它的表象,然后分析它的内在实现,最后查看源代码仔细推敲它到底是怎么实现的。

需要注意的是,列表切片产生的是列表的副本,与原列表不是同一份空间。

x=[1,2,3]
y=x[:]
x[0]=-1
print(y) #输出[1,2,3]

列表切片写操作

接下来探究切片的写操作

>>> x=[1,2,3,4,5]
>>> x[2:0]=100  #在2后面插入若干个元素,应该用列表
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> x[2:0]=[100]
>>> x
[1, 2, 100, 3, 4, 5]
>>> del x[2:3]  #删除切片
>>> x
[1, 2, 3, 4, 5]
>>> x[2:1]=[100] #对于切片x[from:to],会进行预处理to=max(from+1,to)
>>> x
[1, 2, 100, 3, 4, 5]
>>> del x[2:0]  #对于切片del操作,如果from>to,不执行任何操作
>>> x
[1, 2, 100, 3, 4, 5]
>>> del x[2:1]
>>> x
[1, 2, 100, 3, 4, 5]
>>> del x[2:3]
>>> x
[1, 2, 3, 4, 5]
>>> x[2:4]=None
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
>>> x[2:4]=[None]
>>> x
[1, 2, None, 5]

对列表切片进行深入理解:

def between(beg, end, mid):
 # 判断mid是否位于begin和end之间
 return end > mid >= beg or end < mid <= beg


def get_slice(a, beg, end, delta=1):
 # 数组切片get方式
 if delta == 0: raise ValueError("slice step cannot be 0")
 # 将负数下标转化一下
 if beg < 0: beg += len(a)
 if end < 0: end += len(a)
 # 如果转化完成之后依然不在合法范围内,则返回空列表
 if beg < 0 and end < 0 or beg >= len(a) and end >= len(a): return []
 # 如果方向不同,则返回空列表
 if (end - beg) * delta <= 0: return []
 # 将越界的部分进行裁剪
 beg = max(0, min(beg, len(a) - 1))
 end = max(-1, min(end, len(a)))
 ans = []
 i = beg
 while between(beg, end, i):
  ans.append(a[i])
  i += delta
 return ans


def set_slice(a, li, beg, end, delta=1):
 if delta == 0: raise ValueError("slice step cannot be 0")
 if delta == 1:
  # 如果delta==1,那么li的长度可以随意
  if beg < 0: beg += len(a)
  if end < 0: end += len(a)
  beg = max(0, min(beg, len(a) - 1))
  end = max(-1, min(end, len(a)))
  for i in range(beg, end):
   del a[beg]
  for i in reversed(li):
   a.insert(beg, i)
 else:
  # delta!=1,相当于替换
  if len(get_slice(a, beg, end, delta)) != len(li): raise ValueError("array don't match")
  if len(li) == 0: return
  if beg < 0: beg += len(a)
  if end < 0: end += len(a)
  beg = max(0, min(beg, len(a) - 1))
  # 用li中的全部元素逐一替换
  for ind, value in enumerate(li):
   a[ind * delta + beg] = value


def test_getSlice():
 a = list(range(10))
 import random
 for i in range(10):
  beg = random.randint(-15, 15)
  end = random.randint(-15, 15)
  delta = 0
  while delta == 0: delta = random.randint(-15, 15)
  print(len(get_slice(a, beg, end, delta)) == len(a[beg:end:delta]), beg, end, delta)


def test_setSlice():
 import random
 for i in range(10):
  a = list(range(10))
  beg = random.randint(-15, 15)
  end = random.randint(-15, 15)
  delta = 0
  while delta == 0: delta = random.randint(-5, 5)
  sz = len(a[beg:end:delta])
  if delta == 1: sz = random.randint(0, 4)
  li = [random.randint(0, 100) for i in range(sz)]
  set_slice(a, li, beg, end, delta)
  mine = a
  a = list(range(10))
  a[beg:end:delta] = li
  print(a == mine)


test_setSlice()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python分析apache访问日志脚本分享
Feb 26 Python
python 递归遍历文件夹,并打印满足条件的文件路径实例
Aug 30 Python
Python多进程multiprocessing.Pool类详解
Apr 27 Python
Python代码缩进和测试模块示例详解
May 07 Python
python微信好友数据分析详解
Nov 19 Python
python实现得到当前登录用户信息的方法
Jun 21 Python
pycharm new project变成灰色的解决方法
Jun 27 Python
Python Django的安装配置教程图文详解
Jul 17 Python
pytorch 图像预处理之减去均值,除以方差的实例
Jan 02 Python
python烟花效果的代码实例
Feb 25 Python
python实现梯度下降法
Mar 24 Python
解决flask接口返回的内容中文乱码的问题
Apr 03 Python
Python在不同目录下导入模块的实现方法
Oct 27 #Python
Django视图之ORM数据库查询操作API的实例
Oct 27 #Python
浅谈python函数之作用域(python3.5)
Oct 27 #Python
python+pyqt实现右下角弹出框
Oct 26 #Python
python中模块的__all__属性详解
Oct 26 #Python
Python内建函数之raw_input()与input()代码解析
Oct 26 #Python
python分布式环境下的限流器的示例
Oct 26 #Python
You might like
mayfish 数据入库验证代码
2010/04/30 PHP
php并发对MYSQL造成压力的解决方法
2013/02/21 PHP
PHP实现伪静态方法汇总
2016/01/13 PHP
总结的一些PHP开发中的tips(必看篇)
2017/03/24 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
js中键盘事件实例简析
2015/01/10 Javascript
angularjs创建弹出框实现拖动效果
2020/08/25 Javascript
深入理解JavaScript 函数
2016/06/06 Javascript
JS实现随机颜色的3种方法与颜色格式的转化
2017/01/05 Javascript
angularjs的select使用及默认选中设置
2017/04/08 Javascript
在vue中使用v-bind:class的选项卡方法
2018/09/27 Javascript
angularJS1 url中携带参数的获取方法
2018/10/09 Javascript
vue-cli 构建骨架屏的方法示例
2018/11/08 Javascript
JavaScript实现图片轮播特效
2019/10/23 Javascript
Vue分页效果与购物车功能
2019/12/13 Javascript
node使用request请求的方法
2019/12/20 Javascript
Python3基础之基本数据类型概述
2014/08/13 Python
flask中的wtforms使用方法
2018/07/21 Python
python 接收处理外带的参数方法
2018/12/03 Python
python爬虫解决验证码的思路及示例
2019/08/01 Python
详解python方法之绑定方法与非绑定方法
2020/08/17 Python
美国著名的品牌折扣店:Burlington
2017/06/08 全球购物
吉尔德利巧克力公司:Ghirardelli Chocolate Company
2019/03/27 全球购物
Fnac西班牙官网:法国文化和电子产品零售商
2021/03/14 全球购物
自我评价优秀范文分享
2013/11/30 职场文书
生物医学工程专业学生求职信范文分享
2013/12/14 职场文书
工程质量月活动方案
2014/02/19 职场文书
2014年防汛工作总结
2014/12/08 职场文书
个人自荐书范文
2015/03/09 职场文书
求职自我评价范文
2015/03/09 职场文书
新生儿未入户证明
2015/06/23 职场文书
《黄山奇石》教学反思
2016/02/18 职场文书
《追风筝的人》:人心中的成见是座大山,但请不忘初心
2019/11/15 职场文书
Golang实现AES对称加密的过程详解
2021/05/20 Golang
MySQL into_Mysql中replace与replace into用法案例详解
2021/09/14 MySQL
R9700摩机记
2022/04/05 无线电