活动地址: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])
- 如何实现优化?通过
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])
参考资料
|