彻底理解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使用any判断一个对象是否为空的方法
Nov 19 Python
Python实现爬取知乎神回复简单爬虫代码分享
Jan 04 Python
利用python实现数据分析
Jan 11 Python
Python smtplib实现发送邮件功能
May 22 Python
Python3爬虫学习之爬虫利器Beautiful Soup用法分析
Dec 12 Python
Python一个简单的通信程序(客户端 服务器)
Mar 06 Python
jupyter notebook 中输出pyecharts图实例
Apr 23 Python
pandas中的数据去重处理的实现方法
Feb 10 Python
Django 解决新建表删除后无法重新创建等问题
May 21 Python
pyecharts在数据可视化中的应用详解
Jun 08 Python
Python 解析库json及jsonpath pickle的实现
Aug 17 Python
python 对xml解析的示例
Feb 27 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
自制短波长线天线频率预选器 - 成功消除B2K之流的镜像
2021/03/02 无线电
php防止伪造数据从地址栏URL提交的方法
2014/08/24 PHP
Symfony学习十分钟入门经典教程
2016/02/03 PHP
php快速排序原理与实现方法分析
2016/05/26 PHP
处理及遍历XML文档DOM元素属性及方法整理
2013/08/23 Javascript
jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮
2013/10/11 Javascript
原生javascript实现的分页插件pagenav
2014/08/28 Javascript
javascript实现修改微信分享的标题内容等
2014/12/11 Javascript
javascript实现动态表头及表列的展现方法
2015/07/14 Javascript
AngularJS基础 ng-non-bindable 指令详细介绍
2016/08/02 Javascript
jQuery实现的图片轮播效果完整示例
2016/09/12 Javascript
使用get方式提交表单在地址栏里面不显示提交信息
2017/02/21 Javascript
如何写好你的JavaScript【推荐】
2017/03/02 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
2017/05/03 Javascript
基于VUE选择上传图片并页面显示(图片可删除)
2017/05/25 Javascript
webpack 静态资源集中输出的方法示例
2018/11/09 Javascript
详解JavaScript的变量
2019/04/04 Javascript
RxJS的入门指引和初步应用
2019/06/15 Javascript
Python基于回溯法子集树模板实现8皇后问题
2017/09/01 Python
python如何拆分含有多种分隔符的字符串
2018/03/20 Python
浅谈python常用程序算法
2019/03/22 Python
Python、 Pycharm、Django安装详细教程(图文)
2019/04/12 Python
使用selenium和pyquery爬取京东商品列表过程解析
2019/08/15 Python
使用pyinstaller逆向.pyc文件
2019/12/20 Python
python生成并处理uuid的实现方式
2020/03/03 Python
详解python如何引用包package
2020/06/07 Python
Python嵌入C/C++进行开发详解
2020/06/09 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
使用Python通过oBIX协议访问Niagara数据的示例
2020/12/04 Python
LightInTheBox西班牙站点:全球商品在线采购
2016/09/22 全球购物
Mountain Warehouse德国官网:英国户外零售商
2019/08/11 全球购物
网络安全类面试题
2015/08/01 面试题
暑期实习鉴定
2013/12/16 职场文书
计算机求职信
2014/07/02 职场文书
2014年卫生监督工作总结
2014/12/09 职场文书
《认识年月日》教学反思
2016/02/19 职场文书