Python高级特性——切片(Slice)

摘录廖雪峰网站

定义一个list:

1

= ['haha','xixi','hehe','heihei','gaga']

 取其前三个元素:

>>> L[0],L[1],L[2]
('haha', 'xixi', 'hehe')

这个方法有点蠢,因为如果元素非常多,我们需要取其前N个元素,怎么办?

可能会想到用循环:

复制代码

>>> r=[]
>>> n = 3
>>> for i in range(n):
...     r.append(L[i])
...
>>> r
['haha', 'xixi', 'hehe']

复制代码

但是像这种很频繁很常用的操作手段,基本上所有的语言都提供了简单的操作方法,类似Substring方法(俗称取子串),python也提供了类似的方法,这就是切片(Slice).

 例如:

>>> L[0:3]
['haha', 'xixi', 'hehe']

 其中,L[0:3]表示从索引0开始,知道索引3为止,但是不包括索引3,即索引0,1,2.

如果第一个索引为0,还可以省略:

>>> L[:3]
['haha', 'xixi', 'hehe']

 也可以从任意索引开始:

>>> L[1:2]
['xixi']

也可以试试:

>>> L[1:1]
[]

因为,Python也支持倒数取数L[-1],我们来看看是否支持倒数切片:(记住,倒数第一个索引是-1)

>>> L[-2:]
['heihei', 'gaga']
>>> L[-3:-2]
['hehe']

如果感觉还不过瘾,再继续看看:

>>> m = list(range(100))#通过range函数创建一个0-99的数列,组成一个list赋值给m
>>> m
[0, 1, 2, 3, 4, 5, 6, ……,99]

复制代码

>>> m[:10]#取前十个数
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> m[-10:]#取后十个数
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> m[10:20]#取前11-20个数
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> m[:10:2]#前十个数中,每2个数取一个
[0, 2, 4, 6, 8]
>>> m[5:15:3]#第6-15个数中,每3个数取一个
[5, 8, 11, 14]
>>> m[::10]#所有的数中,每10个数取一个
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> m[:]#什么都不写,可以原样复制一个list
[0, 1, 2, 3, 4, 5, 6, 7,……,99]

复制代码

tuple也支持切片特性,只是结果也是一个tuple:

>>> n = (1,3,5,7)
>>> n[:3]
(1, 3, 5)

再来看看字符串:

>>> 'abcdefghjklmn'[::2]
'acegjln'

字符串也支持切片,只是结果也是一个字符串。

再看一个例子:

利用切片功能,编写一个函数trim(str),类似Python中的strip()功能——去除字符串首尾的空格:

复制代码

>>> def trim(str):
...     while str[:1]==' ':
...             str = str[1:]
...     while str[-1:] == ' ':
...             str = str[:-2]
...     return str
...
>>> trim('  abc  hh  welcome!      ')
'abc  hh  welcome!'

复制代码

理解extended slice

    前面那一部分相对来说还是比较好理解的。现在,如果我们有一些其他的要求,比如说,我们想返回数组里面索引为奇数的元素,或者索引为偶数的元素,那么该怎么办呢?

我们可以有几种办法来做,其中的一种就是采用extended slice,一个典型的解决方法如下:

>>> l[::2]  
[0, 2, 4, 6, 8]  
>>> l[1::2]  
[1, 3, 5, 7, 9]  
>>>   

    前面这种包含两个冒号的样式是怎么回事呢?

     实际上,我们这边第一个冒号隔开的这两个部分和前面的意思是一样的,就是指定数组中间元素的区间。所以前面第一个l[::2]前面就是指的整个数组的元素。而后面那个部分则是指的一个步长。这表示什么意思呢?就是既然我们前面指定的是整个数组,那么它就是从0开始,然后每次访问后面相邻的元素。而设置为2之后呢,则访问后面和它距离为2的元素,而不是直接相邻的元素。这样,我们也就容易理解l[1::2],它就是从元素1开始到结尾的元素集合里取间隔为2的这些元素。

    到这一步,就离我们理解前面那个古怪的l[::-1]很接近了。我们前面的这个取步长是将步长设置为正数,所以在取元素的集合里它表示从左到右的取指定步长覆盖的元素。如果我们将步长设置为负数呢?我们来看:

>>> l[1:9:-1]  
[]  
>>> l[9:1:-1]  
[9, 8, 7, 6, 5, 4, 3, 2]

    有了前面这一部分的代码,相信就不难理解了。我们取区间[1, 9),结果取步长为-1的时候返回的是一个空的集合。而我们取9到1的时候,步长为-1取出来了倒序的数组。这是因为如果我们指定的步长为负数的话,那么它必须和数据指定的区间方向一致。也就是说,如果我们前面指定的区间是从数组小的索引到大的索引,那么我指定的步长必然也要从小到大。所以必须为正数。而如果我们指定的区间是从后面往前的话,则步长必须指定为负数。否则返回的结果都是空的数组。

猜你喜欢

转载自blog.csdn.net/fireflylane/article/details/84671693