美文网首页我爱学编程
12. Python | 高级特性_切片

12. Python | 高级特性_切片

作者: 家和万事亨 | 来源:发表于2019-05-02 21:23 被阅读5次

    引入切片的概念

    从一个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('测试成功!')
    

    相关文章

      网友评论

        本文标题:12. Python | 高级特性_切片

        本文链接:https://www.haomeiwen.com/subject/nhdnnqtx.html