彻底理解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基于Pymssql模块实现连接SQL Server数据库的方法详解
Jul 20 Python
Python数据分析之如何利用pandas查询数据示例代码
Sep 01 Python
python3爬取各类天气信息
Feb 24 Python
django允许外部访问的实例讲解
May 14 Python
Python实现将Excel转换成xml的方法示例
Aug 25 Python
Python一个简单的通信程序(客户端 服务器)
Mar 06 Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
Mar 22 Python
Python for循环与range函数的使用详解
Mar 23 Python
Pyinstaller打包.py生成.exe的方法和报错总结
Apr 02 Python
python的sys.path模块路径添加方式
Mar 09 Python
Python小白不正确的使用类变量实例
May 29 Python
python openCV实现摄像头获取人脸图片
Aug 20 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
Yii学习总结之数据访问对象 (DAO)
2015/02/22 PHP
Linux下源码包安装Swoole及基本使用操作图文详解
2019/04/02 PHP
Ctrl+Enter提交内容信息
2006/06/26 Javascript
共享自己写一个框架DreamScript
2007/01/20 Javascript
ImageZoom 图片放大镜效果(多功能扩展篇)
2010/04/14 Javascript
js 链式延迟执行DOME
2012/01/04 Javascript
json格式的时间显示为正常年月日的方法
2013/09/08 Javascript
js日期对象兼容性的处理方法
2014/01/28 Javascript
angularjs中的单元测试实例
2014/12/06 Javascript
jQuery中wrapAll()方法用法实例
2015/01/16 Javascript
微信小程序 实例开发总结
2017/04/26 Javascript
基于Two.js实现星球环绕动画效果的示例
2017/11/06 Javascript
浅谈Vue SSR 的 Cookies 问题
2017/11/20 Javascript
three.js实现3D模型展示的示例代码
2017/12/31 Javascript
vue项目上传Github预览的实现示例
2018/11/06 Javascript
Vue2.x Todo之自定义指令实现自动聚焦的方法
2019/01/08 Javascript
详解ES6 Promise的生命周期和创建
2019/08/18 Javascript
[51:26]VP vs VG 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python 正则式使用心得
2009/05/07 Python
Flask框架中request、请求钩子、上下文用法分析
2019/07/23 Python
python实现数字炸弹游戏程序
2020/07/17 Python
Python操作dict时避免出现KeyError的几种解决方法
2020/09/20 Python
canvas三角函数模拟水波效果的示例代码
2018/07/03 HTML / CSS
英国手机壳购买网站:Case Hut
2019/04/11 全球购物
房地产还款计划书
2014/01/10 职场文书
倡议书范文
2014/04/16 职场文书
高职教师先进事迹材料
2014/08/24 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
二年级语文下册复习计划
2015/01/19 职场文书
2016中考冲刺决心书
2015/09/22 职场文书
小学生禁毒教育心得体会
2016/01/15 职场文书
公文写作:工伤事故分析报告怎么写?
2019/11/05 职场文书
goland 清除所有的默认设置操作
2021/04/28 Golang
教你用python实现12306余票查询
2021/06/30 Python
Redis实现订单过期删除的方法步骤
2022/06/05 Redis
Spring Boot项目如何优雅实现Excel导入与导出功能
2022/06/10 Java/Android