12. Python | 高级特性_切片

引入切片的概念

从一个list或者tuple中取出部分元素,这是非常常见的操作。比如,一个list如下:

>>> L = ['张三','李四','王五','赵六','郑七']

取前3个元素,应该怎么做?
笨方法(最基础的方法):

>>> [L[0],L[1],L[2]]
['张三','李四','王五']

之所以说这是笨方法,因为如果扩展一下,要取前N个元素,就没办法逐一去写了。
取前N个元素,也就是索引为0~(N-1)的元素,可以用循环:

>>> r = []
>>> n = 3
>>> for i in range(n):
...    r. append(L[i])
...
>>> r
['张三','李四','王五']

对于经常取指定索引范围的操作,用循环十分繁琐, 因此Python提供了切片(slice)操作符 [:] ,能大大简化这种操作。

对应上面的问题,取前三个元素,用一行代码就可以完成切片:

>>> L[0:3]
['张三','李四','王五']

L[0:3]表示,从索引0开始取,一共取3 - 0 = 3个元素,也就是索引012

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

>>> L[0:3]
['张三','李四','王五']
>>> L[:3]
['张三','李四','王五']

也可以从索引1开始,取出2个元素出来:

>>> L[1:3]
['李四','王五']

类似的,既然Python支持L[-1]取倒数第一个元素,那么它同样支持倒数切片,试试:

>>> L[-1:]
[郑七]
>>> L[-2:-1]
[赵六]

L[-1: ]表示, 从倒数第一个元素开始, 取0 - (-1) = 1个元素, 0被省略了.
记住,倒数第一个元素的索引是-1
切片操作十分有用。我们先创建一个0~99的数列:

>>> L = list(range(100))
>>> L
[0, 1, 2, 3, . . . , 99]

可以通过切片轻松取出某一段数列。比如前10个数:

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

后10个数:

>>> L[-10: ]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

第11~20个数:

>>> L[10: 20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

前十个数, 每两个一组取第一个:

>>>  L[: 10: 2]
[0, 2, 4, 6, 8]

所有数, 每五个数一组取第一个:

>>> L[: : 5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

甚至什么都不写, 只写[: ]就可以原样复制一个list:

>>> L[: ]
[0, 1, 2, 3, . . . , 99]

tuple也是一种list, 唯一区别是tuple不可变. 因此, tuple也可以用切片操作, 只是操作的结果仍是tuple:

>>> (0, 1, 2, 3, 4, 5)[: 3]
(0, 1, 2)

字符串'xxx'也可以看成是一种list, 每个元素就是一个字符. 因此, 字符串也可以用切片操作, 只是操作的结果仍是字符串:

>>> 'ABCDEFG'[: 3]
'ABC'
>>> 'ABCDEFG'[: : 3]
'ADG'

在很多编程语言中, 针对字符串提供了很多各种各样的截取函数(例如: substring), 其实目的就是对字符串切片. Python没有针对字符串的截取函数, 只需要切片这一个操作就可以完成, 非常简单.

总结一下切片的特点

  • 切片可以对list、tuple、字符串进行操作
  • 写法: [x: y]
    1. x表示从索引x位置的元素开始取.
      x == 0时, x可以省略不写, 表示为 [: y]
      >>> L = [0, 1, 2, 3, 4, 5]
      >>> L[0: 1]
      [0]
      >>> L[: 1] # 注意: L[0: 1] == L[: 1], 只是省略了0, 切片结果是一样的
      [0]
      x < 0时, 切片的结果, 包含从倒数第x个元素开始到最后的所有元素, 例如:
      >>> L[-3: ] # 从倒数第3个元素开始, 向后切片到最后一个元素
      [3, 4, 5]
    2. y的值表示取元素到索引y之前.
      x == 1, y == 3时,表示从索引1开始取, 到索引3之前, 也就是索引1, 2的元素
      >>> L = [0, 1, 2, 3, 4, 5]
      >>> L[1: 3]
      [1, 2]
      x == 0, y == 3时, 进行切片, 结果是取索引为0, 1, 2的元素:
      >>> L[0: 3] # 此时L[x: y] == L[0: 3], 也可以写成L[: 3]
      [0, 1, 2]
      y省略时, 表示从索引x开始取, 一直取到最后一个元素:
      >>> L = [1, 2, 3, 4, 5]
      >>> L[2:] # 从索引2(对应第3个元素)开始, 到最后一个元素
      [3, 4, 5]
      >>> L[-2:] # 从索引-2(对应倒数第2个元素)开始, 到最后一个元素
      [4, 5]
      y < 0时, 表示从索引x开始取, 直到倒数第y个元素之前:
      >>> L = [1, 2, 3, 4, 5]
      >>> L[: -2] # 倒数第2个元素为4, 所以取4之前的所有元素
      [1, 2, 3]
      >>> L[1: -1] # 表示从索引1开始取, 直到索引-1之前的所有元素
      [2, 3, 4]
      >>> L[-4: -2] # 从倒数第4个元素开始,倒数第2个元素之前的所有元素
      [2, 3]
    3. 切片时如果要进行更细致的要求, 此时引入z表示具体的取值方式, 写作[x: (x + y): z]
      z省略掉时, 表示将取值范围内的所有元素都取到, 例如:
      >>> L = [0, 1, 2, 3, 4, 5]
      >>> L[: 5] # 取值范围包含5个元素, 直接取范围内的全部元素
      [0, 1, 2, 3, 4]
      z为具体数值时, 则对取值范围内的元素分组, 每z个元素分为一组, 取每组的第一个元素. 例如:
      >>> L = [0, 1, 2, 3, 4, 5]
      >>> L[: 5: 2] # 取值范围含5个元素(5 - 0 =5), 每2个为一组, 每组取第一个
      [0, 2, 4]
      >>> L[1: 4: 3] #取值范围含3个元素(4 - 1 = 3), 每3个为一组, 每组取第一个
      [1]

练习

  • 利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法:注意, 体会代码中的两个 while循环语句 的作用.
# -*- coding: utf-8 -*-
def trim(s):
    # 这里放置第一个循环, 将所有的前部空格干掉
    # 当首字符是空格时, 切片表示为s[: 1] == ' '
    while s[: 1] == ' '
        # 去掉前部空格, 从第二个元素开始向后切片, 结果赋值给 s
        s = s[1: ]
    # 这里放置第二个循环, 将所有尾部的空格干掉
    # 尾部空格, 切片表示为s[-1: ] == ' '
    while s[-1: ] == ' '
        #去掉空格, 从倒数第二个元素开始切片
        s = s[: -1]
    return s
# 测试:
# 去掉尾部空格的验证
if trim('hello  ') != 'hello':
    print('测试失败!')
# 去掉开头空格的验证
elif trim('  hello') != 'hello':
    print('测试失败!')
# 去掉首尾空格的验证
elif trim('  hello  ') != 'hello':
    print('测试失败!')
# 去掉首尾空格, 但是不改变中间空格的验证
elif trim('  hello  world  ') != 'hello  world':
    print('测试失败!')
# 空字符串的验证
elif trim('') != '':
    print('测试失败!')
# 字符串只含空格的验证
elif trim('    ') != '':
    print('测试失败!')
# 如果以上所有情况都验证无误, 则输出'测试成功!'
else:
    print('测试成功!')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • 取一个list或tuple的部分元素是非常常见的操作,比如,一个list如下 L = ['Michael','Sr...
    CaesarsTesla阅读 157评论 0 0
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,782评论 0 38
  • 基础篇NumPy的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格(...
    oyan99阅读 5,122评论 0 18
  • 一、python 变量和数据类型 1.整数 Python可以处理任意大小的整数,当然包括负整数,在Python程序...
    绩重KF阅读 1,682评论 0 1
  • 空气中流动的热浪 仿佛快要把草地融化 水泥地热的发骚 让上面的人们躁动不安 麦田期待着他的来到 她渴望着被滋润 大...
    不敢说爱你阅读 382评论 2 4