美文网首页
Effective Python(6): 单次切片操作,不要同时

Effective Python(6): 单次切片操作,不要同时

作者: warmsirius | 来源:发表于2019-09-29 08:33 被阅读0次

    一、stride参数

    除了基本的切片操作(参考Effective Python(5): 了解切割序列的方法), Python还提供了somelist[start:end:stride]形式的写法,以实现步进式切割。

    例如:

    a = ["red", "orange", "yellow", "green", "blue", "purple"]
    odds = a[::2]
    evens = a[1::2]
    print(odds)
    print(evens)
    
    # Results
    ['red', 'yellow', 'blue']
    ['orange', 'green', 'purple']
    

    二、问题

    问题在于,采用stride方式进行切片时,经常会出现不符合预期的结果。

    1. Python中有一个技巧,利用-1做步进值,可以将以字节形式存储的字符串反转过来

    >>> x = b'diagnosor'
    >>> y = x[::-1]
    >>> y
    b'rosongaid'
    

    但是这种技巧对字节串和ASCII字符有用,对已经编码成UTF8字节串的Unicode字符来说,则无法奏效。

    >>> w = '谢谢'
    >>> x = w.encode('utf8')
    >>> x
    b'\xe8\xb0\xa2\xe8\xb0\xa2'
    >>> y = x[::-1]
    >>> y
    b'\xa2\xb0\xe8\xa2\xb0\xe8'
    
    >>> y.decode('utf8')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa2 in position 0: invalid start byte
    

    2. 步长举例

    a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
    a[::2]        # ['a', 'c', 'e', 'g']
    a[::-2]       # ['h', 'f', 'd', 'b']
    
    a[2::2]       # ['c', 'e', 'g']
    a[-2::-2]     # ['g', 'e', 'c', 'a']
    a[-2:2:-2]   # ['g', 'e']
    a[2:2:-2]    # []
    

    通过上面例子可以看出:切割列表时,如果指定了stride,那么代码可能会变得相当费解。在一对括号中写上3个数字显得太过拥挤,导致代码难以阅读。

    解决:

    • a. 不把startendstride写在一起。
    • b. 如果非要用stride尽量采用正值,同时省略startend索引。
    • c. 如果一定要配合start或end索引来使用stride,先做步进式切片,把切割结果赋给某个变量,然后在那个变量上面做第二次切割。
    b = a[::2]
    c = b[1:-1]
    

    这种先做步进切割,再做范围切割的办法,会多产生一份原数据的浅拷贝。执行第一次切割操作时,应该尽量缩减切割后的列表尺寸。

    注意:
    如果开发程序对执行时间或内存用量的要求非常严格,以致不能采用两阶段切割法,那就考虑Python内置的itertools模块中的islice方法,这个方法不允许为 startendstride指定负值。

    三、要点

    • 尽量使用stride为整数,且不带startend索引的切割操作。
    • 避免用负数做stride
    • 尽量不要在一个列表括号中同时使用startend、和stride,如果确实需要执行这种操作,那就考虑将其拆解为两条赋值语句,其中一条做范围切割,另一条做步进切割,或考虑用内置的itertoolsislice方法

    相关文章

      网友评论

          本文标题:Effective Python(6): 单次切片操作,不要同时

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