极简python之切分

时启发 2024-05-16 22:11:24

(最小化python 总觉得不是个合适的名字,改为极简python)

上篇说到列表的切分,从通过索引值对列表某一个元素的访问,到通过索引值对某一个列表一个元素的切分,然后到多个元素的切分。并了解到切分中用于表示切分范围的格式,是通过以冒号分隔的两部分数值组成,表示从左侧索引位置(包含)到右侧索引位置(不包含)范围之内的数据,对于列表而言,切分返回的仍然是列表。

说到范围,python内置函数中有一个函数range(),最多可以包含3个参数,其函数定义这样的(见官方文档):class range(stop)或class range(start, stop[, step])。用以表示从start到stop的一个序列,如果指定了step值,那么将start将以步长为step的“速度”,逐步“递进”到stop值。如果step没有指定,则step默认为1。

现在还是通过读取列表中一个一个单独的元素来理解,不过我们需要for语句的帮助。这里先假设列表a=list(range(10, 20)),表示a=[10,11,...,19],共10个元素。现在我们取出索引值i位置的值,我们知道,如果不使用for循环的话,应该是a[i],但是如果采用i的话,假定这里i=5,我们能用笨办法想到的是:

图1 利用range函数和for循环,取列表a中索引位置为5处的值

好的,因为我是一个执拗的人,要求range函数和for语句都必须使用,而且需要对上图中的循环语句进行一下改进,因为循环如无意外将遍历10次(对应a的长度),除非是在自定义函数中利用return将返回值返回了,但同样存在位置i之前空转的情形。先一边考虑,一边先改成函数的形式,函数名就叫get_value_at好了,见图2:

图2 get_value_at函数的定义

在get_value_at函数定义中,我们定义了两个参数,index表示索引位置,arr表示数组,返回值为arr[index]的值。增加了许多代码,也写了不少废话。for循环还能不能改呢,当然,见下图3:

图3 通过改变range的开始值,进一步减少循环次数

其中的if语句,由于i肯定等于index,同样可以删除掉了。这是取一个元素值的情况,相当于直接a[i]的复杂废话版。接下来我们试着改写成为取range函数定义范围内列表的切片的情况。见图4:

图4 取指定范围的列表切片的函数

这个有点a[5:6]的味道了。要知道range可以有三个参数,所以,如果我们想取其中某一部分,比如奇数位索引位置的元素,就可以这样调用上图中的get_cut_of函数,图5:

图5 取索引位置为奇数位置的列表切片

列表切片中有没有对应三个参数的表示法呢?有的。python替你想到了,用两个冒号分隔三个数字即可(同样分别表示start,stop,step),比如对应上图的range(1,len(a),2),可以表示为1:len(a):2,对应列表a的切片为a[1:len(a):2],然后,一个冒号的时候,我们知道start不写表示从0开始,stop不写表示到列表尾部(最后一个元素索引+1位置),依次类推,a[1:len(a):2]可以jian简化为a[1::2]。见图6:

图6 包含了步长的切片表示法

写到这里确实感觉到前面写了一堆函数,绕的圈子有点大,确实是,这就是python为啥是极简的原因,如果一种表达特别复杂,python里应该会有更简单的表示方法。上面一直坚持用的函数和for循环也是。get_cut_of针对for循环部分的改写可以是这样的,见图7:

图7  列表推导式替代for循环

替换for循环又长得像for语句的这个语句arr[i] for i in rng就是列表推导式,可以将for循环和增加新元素到列表的代码合并到一行。有点像倒装句,for i in rng: arr[i]的倒装句。这块需要耐心消化一下。所以获取切边又多了一种用列表推导式表示的等同形式,见图8:

图8 切片的列表推导式形式的表示

尽管这些比不上python做到极致的简化(a[1::2]),但希望以上过程能帮助理解切片,这才是本篇的最终目的。

1 阅读:93

时启发

简介:读书笔记,编程经验,旅途见闻,人生感悟