彻底理解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 修改文件指定行的方法
May 15 Python
Python里disconnect UDP套接字的方法
Apr 23 Python
高质量Python代码编写的5个优化技巧
Nov 16 Python
Python 实现Windows开机运行某软件的方法
Oct 14 Python
Python中作用域的深入讲解
Dec 10 Python
Python使用正则实现计算字符串算式
Dec 29 Python
python如何获取apk的packagename和activity
Jan 10 Python
Flask模板引擎Jinja2使用实例
Apr 23 Python
Django中使用Json返回数据的实现方法
Jun 03 Python
Python类及获取对象属性方法解析
Jun 15 Python
Python爬虫实现HTTP网络请求多种实现方式
Jun 19 Python
python 实现汉诺塔游戏
Nov 28 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
PHP小教程之实现双向链表
2014/06/12 PHP
Yii2隐藏frontend/web和backend/web的方法
2015/12/12 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
2016/11/25 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
html中的input标签的checked属性jquery判断代码
2012/09/19 Javascript
通过jQuery源码学习javascript(一)
2012/12/27 Javascript
文本框文本自动补全效果示例分享
2014/01/19 Javascript
使用JavaScript实现旋转的彩圈特效
2015/06/23 Javascript
BootStrap中的table实现数据填充与分页应用小结
2016/05/26 Javascript
使用JS中的exec()方法构造正则表达式验证
2016/08/01 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
2016/12/18 Javascript
原生js实现节日时间倒计时功能
2017/01/18 Javascript
vue+express 构建后台管理系统的示例代码
2018/07/19 Javascript
JavaScript学习笔记之DOM操作实例分析
2019/01/08 Javascript
JavaScript剩余操作符Rest Operator详解
2019/07/20 Javascript
[02:10]三分钟回顾完美世界城市挑战赛
2019/01/24 DOTA
python使用scrapy解析js示例
2014/01/23 Python
Python selenium抓取微博内容的示例代码
2018/05/17 Python
python一键去抖音视频水印工具
2018/09/14 Python
python可视化实现代码
2019/01/15 Python
Python实现性能自动化测试竟然如此简单
2019/07/30 Python
python元组和字典的内建函数实例详解
2019/10/22 Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
2019/10/30 Python
Python namedtuple命名元组实现过程解析
2020/01/08 Python
Python+appium框架原生代码实现App自动化测试详解
2020/03/06 Python
在 Pycharm 安装使用black的方法详解
2020/04/02 Python
python cv2.resize函数high和width注意事项说明
2020/07/05 Python
HTML5的结构和语义(5):交互
2008/10/17 HTML / CSS
中国首家奢侈品O2O网购平台:第五大道奢侈品网
2017/12/14 全球购物
软件测试企业面试试卷
2016/07/13 面试题
vue路由实现登录拦截
2021/03/24 Vue.js
应届毕业生自我评价分享
2013/12/15 职场文书
缓刑人员的思想汇报
2014/01/11 职场文书
2013年研究生毕业感言
2014/02/06 职场文书
2016三八妇女节校园广播稿
2015/12/17 职场文书