切片,就像面包,给几刀,切成一片一片,可以做成吐司,也可以做成三明治,口味更佳:

列表(list)、元组(tuple)、字符串(str)都能进行切片,得到子片段,实际上切片操作比想象的要强大很多,能取值,亦能赋值。

忽略最后一个元素

切片是用下标和冒号来描述的,比如s[2:13]。对于2, 3, ..., 12这个序列,表达为[2, 13),左闭右开,比[2, 12](1, 13)都更合理,理由如下:

  1. 上限减去下限等于元素个数,比如13 - 2 = 11,刚好就有11个元素。
  2. 连续的范围没有重叠,比如[2, 13)[13, 25) 是两个连续的范围,13只会包含在后一个里。

下标从0开始

对于10个元素,写成[0, 10)[1, 11)更合理,理由如下:

  1. N个元素,[0, N)[1, N+1)写法更简洁,不需要+1

  2. 某个元素的下标等于排在它前面元素的个数,方便使用,比如:

    0 1 2 3 4 5 6 7 8 9
    ^
    前面有4个元素

好用的切片

以上两个数学理论给切片使用带来了很多好处:

  • 当只有最后一个位置信息时,可以快速看出有几个元素,比如my_list[:3]返回3个元素。

  • 当起止位置信息都可见时,可以快速计算出长度,用stop - start就可以了,比如my_list[1:3]长度为2。

  • 利用任意一个下标把序列切割成不重叠的两部分,只要写成my_list[:x]my_list[x:]就可以了,比如

    >>> my_list = [10, 20, 30, 40, 50, 60]
    >>> my_list[:3]
    [10, 20, 30]
    >>> my_list[3:]
    [40, 50, 60]

Python里的范围(range)也是忽略最后一个元素,下标从0开始的。

切片间隔

切片除了s[a:b],还有第三个下标s[a:b:c],意思是对s在a和b之间以c为间隔取值,c还可以为负,负值意味着反向取值。比如:

>>> s = "bicycle"
>>> s[::3]
"bye"
>>> s[::-1]
"elcycib"
>>> s[::-2]
"eccb"

a:b:c更严谨的描述是start:stop:step

语法如此简洁,用脚想也知道是Python魔法方法干的好事!在对s[a:b:c]进行求值的时候,Python实际上会调用s.__getitem__(slice(a, b, c)),熟悉的配方,熟悉的味道。slice(a, b, c)a:b:c用在[]中返回的切片对象,slice()是Python内置函数,示例:

invoice = "Mini Kit $34.95 1 $ 34.95"
SKU = slice(0, 8)
print(invoice[SKU])

切片赋值

切片有一个强大功能是给切片赋值,如果把切片放在赋值语句的左边,或把它作为del操作的对象,我们就可以对序列进行嫁接、切除或就地修改操作。示例:

>>> l = list(range(10))
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del l[5:7]
>>> l
[0, 1, 2, 3, 4, 7, 8, 9]
>>> l[3:2] = [11, 22]
>>> l
[0, 1, 2, 11, 22, 3, 4, 7, 8, 9]
>>> l[2:5] = [100]
>>> l
[0, 1, 100, 3, 4, 7, 8, 9]

注意,如果赋值的对象是一个切片,那么赋值语句的右侧必须是个可迭代对象,即使只有单独一个值,否则会报错:

>>> l[2:5] = 100
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: can only assign an iterable

多维切片

除了一维切片,Python还支持多维切片,这在多维数组中能体现出来。NumPy是Python第三方库,提供了高阶数组,使得Python成为科学计算应用的主流语言。示例:

>>> import numpy
>>> a = numpy.arange(12)
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> a.shape
(12,)
>>> a.shape = 3, 4
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[:, 1]
array([1, 5, 9])
>>> a[1:2, 2:3]
array([[6]])
>>> a[1:3, 2:4]
array([[ 6, 7],
[10, 11]])

在NumPy中,省略号...用作多维数组切片的快捷方式,如果x是四维数组,那么x[i, ...]就是x[i, :, :, :]的缩写,比如:

>>> a.shape = 2, 2, 3
>>> a
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
>>> a[:, :, 1]
array([[ 1, 4],
[ 7, 10]])
>>> a[..., 1]
array([[ 1, 4],
[ 7, 10]])

小结

本文介绍了Python强大的切片操作,因为忽略最后一个元素和下标从0开始,所以切片用起来特别顺手,除了开始和结尾,还能设置切片间隔,间隔为负可以反向取值。切片赋值是切片另一个强大功能,需要注意的是赋值语句的右侧必须是个可迭代对象。

参考资料:

《流畅的Python》

https://blog.wz52.cn/archives/174.html

能取值亦能赋值的Python切片的更多相关文章

  1. div赋值,取值和input赋值,取值

    一.div取值 <div id="txtXiaofei" class="txt-panel">你好</div> 获取div的值$(&qu ...

  2. input标签元素,value属性取值问题,赋值

    验证val:<input type="text" id="id" name="name" value="空值"&g ...

  3. jquery radio 取值 取消选中 赋值

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. jquery input 赋值和取值

    记录一下: 在写一个input赋值,二话不说就直接利用了$('#xx').val()来进行取值和赋值,取值ok,赋值后利用alert显示正确,但是在html上并没有正确的显示出来,后来改为使用如下代码 ...

  5. Python数据科学手册-Pandas:数据取值与选择

    Numpy数组取值 切片[:,1:5], 掩码操作arr[arr>0], 花哨的索引 arr[0, [1,5]],Pandas的操作类似 Series数据选择方法 Series对象与一维Nump ...

  6. Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)

    Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...

  7. python 字典(formkey 建立 取值 赋值 删除 )

      formkey快速建立空字典   result = {}.fromkeys(['name','age','job'],None) print(result)   #往字典里添加元素 result. ...

  8. Python_关于多线程下变量赋值取值的一点研究

    关于多线程下变量赋值取值的一点研究 by:授客 QQ:1033553122 1.代码实践1 #!/usr/bin/env python # -*- coding:utf-8 -*- __author_ ...

  9. jQuery radio的取值与赋值

    取值: $("input[name='radioName']:checked").val(); 赋值: $("input[name='radioName'][value= ...

随机推荐

  1. MySQL数据库操作生成UUID

    问题描述: 通过数据库操作,生成无横线的uuid,同时插入至数据库之中. 因为我要给项目做一些测试数据,项目的主键为32位无'-'的uuid,然后在数据库中,通过数据库操作,然后插入一些测试数据. 生 ...

  2. CAS客户端和服务器配置https证书

    关于如何生成https证书可以看这篇文章: java生成Https证书,及证书导入的步骤和过程 下面整理cas如何整合https: cas服务器端部署(TLS[https]) 1.生成证书: 参照ja ...

  3. MacOS Big Sur开HiDPI

    我自己的环境: 开启hidpi的目的是为了让显示更加细腻,代价是缩小了显示范围. 自己在网上看了很多帖子,也尝试了几种,有些方法已经不再适合Big Sur系统了,所以本文提供一种可用的,在Big Su ...

  4. Think in Java 第三章操作符

    Think in Java 第三章操作符 赋值 对象赋值 ​ 我们真正操作的是对对象的引用.所以倘若"将一个对象赋值给另一个对象",实际上是将"引用"从一个地方 ...

  5. Jenkins开启丢弃旧的构建?你可要小心啊!

    玩Devops的小伙伴应该对Jenkins都有了解. Github上16.8k的Star的项目,1500+的构建.发布等自动化插件可供选择,事实上的业界CICD标准领导者. JFrog.Coding等 ...

  6. Java创建线程四种方式

    1.继承Thread类 public class MyThread extends Thread { public MyThread() { } public void run() { for(int ...

  7. Common Divisors CodeForces - 1203C

    题意: 给你n个数,让你找出来公因子有多少个.公因子:对于这n个数,都能被这个公因子整除 题解: 只需要找出来这n个数的最大公因子x,然后找出来有多少不同数能把x给整.(因为我们可以保证x可以把这n个 ...

  8. Nginx基础 - Nginx+Lua实现灰度发布与WAF

    1.Nginx加载Lua环境默认情况下Nginx不支持Lua模块, 需要安装LuaJIT解释器, 并且需要重新编译Nginx, 建议使用openrestry 1)环境准备 [root@localhos ...

  9. VS2010的单元测试(二)

    四.附加测试属性 附加测试属性,在默认生成的测试代码是使被注释掉的,取消注释就可以使用. 例如,要在执行测试前,输出测试开始时间,在执行测试后,输出测试结束时间.代码如下: [ClassInitial ...

  10. 【非原创】LightOJ-1274 Beating the Dataset【期望dp】

    学习博客:戳这里