流畅的Python读书笔记(三)序列:切片应用及原理浅析

活动地址:CSDN21天学习挑战赛

流畅的Python读书笔记(三)序列:切片应用及原理浅析


本篇笔记简略介绍切片的使用,同时会简单说明,切片操作时,Python解释器会进行哪些调用。

假定你对切片有了一定的了解。

切片的使用

切片较重要的作用有两个:提取感兴趣的数据;透过切片修改原序列

  • 提取感兴趣的数据

    • 先简单提一下切片语法。

      语法:对于一个序列x。可以使用x[a:b:c]的方式对其进行切片。a表示切片起始索引,b表示切片结束索引,c表示切片步长。

      切片操作的范围有一个口诀,左闭右开,就是说,切片范围为[a,b),能够取到下标为a的元素,取不到下标为b的元素。而切片步长是指从起始下标a开始,每次加上c后,取下一个元素。c可以省略,当省略时,c的值默认为1。当c为正数时,若a省略,则a默认为序列起始,即a=0,若b省略,则b默认为序列结尾,即b=len(x);当c为负数时,若a省略,则a默认为序列末尾,即a=-1,若b省略,则b默认为序列开始,即b= —(len(x) + 1)

      示例:

      >>> l = list(range(10))
      >>> l
      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      >>> l[2:5]
      [2, 3, 4]
      >>> l[:]
      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      >>> l[-1:-(len(l) + 1):-1]
      [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
      
  • 透过切片修改原序列

    • 如果把切片放在赋值语句的左边,或把它作为del操作的对象,我们就可以对序列进行嫁接、切除或就地修改操作。

      >>> l = list(range(10))
      >>> l
      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      >>> l[2:5] = [20, 30]
      >>> l
      [0, 1, 20, 30, 5, 6, 7, 8, 9]
      >>> del l[5:7]
      >>> l
      [0, 1, 20, 30, 5, 8, 9]
      >>> l[3::2] = [11, 22]
      >>> l
      [0, 1, 20, 11, 5, 22, 9]
      >>> l[2:5] = 100  ①
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>TypeError: can only assign an iterable >>> l[2:5] = [100]
      >>> l
      [0, 1, 100, 22, 9]
      

      ①如果赋值的对象是一个切片,那么赋值语句的右侧必须是个可迭代对象。即便只有单独一个值,也要把它转换成可迭代的序列。


前面提到了切片的范围是左闭右开,即[a,b)。下面简单说一下为什么是这样。

为什么切片和区间会忽略最后一个元素

  • 当只有最后一个位置信息时,可以很快推断出切片和区间中有几个元素。比如切片x[:4],我们可以通过4直接判断出,切片中有4个元素。

  • 起始位置和终止位置都已知时,推断切片和区间中有几个元素。比如切片x[a:b],我们可以直接推断出,切片中有b-a个元素。

  • 便于分隔序列。比如序列x,向将其中的数据从中间某个元素处分隔开,那么找到分隔点的下标索引mid,然后切片x[:mid],x[mid:]

Python解释器对[]的处理

假定现有一个序列,这里具体一点,就是一个列表seq。对其进行切片seq[start:stop:step], 在前面这个表达式求值时,Python解释器会调用seq.__getitem__(slice(start, stop, step))

上面slice(start, stop, step)会返回一个slice对象。

  • 优化切片代码

    先说明会用到的文件animals.txt,其中的内容如下:

    name____spe__age
    Tom    Cat   1
    Jerry  Mouse 1
    
    • 之前,我们对序列切片都是在[]中直接指定切片范围。比如:
    infos = open('animals.txt', 'r')
    # 提取动物名称
    for info in infos:
        print(info[0:5])
    
    #输出结果为:
    #name_
    #Tom
    #Jerry
    
    • 如何实现优化?通过slice对象进行切片,进而使代码可读性增强。
    infos = open('animals.txt', 'r')
    animal_name = slice(0, 5)  #这是最重要的优化,提高了代码可读性
    print(animal_name)
    print(type(animal_name))
    # 提取动物名称
    for info in infos:
        print(info[animal_name])
    
    #输出结果为:
    #slice(0, 5, None)
    #<class 'slice'>
    #name_
    #Tom  
    #Jerry
    

参考资料

  • 流畅的Python
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值