Python3 - 切片技巧-列表(list),字符串(str),字节(bytes)

Python3 - 切片技巧-列表(list),字符串(str),字节(bytes)

列表切片是 Python 提供的便捷功能之一。切片通常用于访问有序集合中的元素范围。切片的最简单用法是内置类型”list”,”str”和”bytes”。切片基本语法形式是”somelist[start:end:stride]”,其中”start”是包含在内的,而”end”是排斥的。

举个例子:

1
2
3
4
5
a = [1, 2, 3, 4, 5, 6, 7, 8]
print ('first four:', a[:4])
print ('last four:', a[-4:])
print ('middle two:', a[3:-3])

将输出

1
2
3
first four: [1, 2, 3, 4]
last four:  [5, 6, 7, 8]
middle two: [4, 5]

从头开始切片时,我们应该省略零索引,而在切片到列表末尾时,建议省略最终索引。 a[:5]优于a[0:5] a[5:]优于a[5:len(a)]

使用负数进行切片可以相对于列表末尾偏移。

1
2
3
4
5
6
7
8
# a = [1, 2, 3, 4, 5, 6, 7, 8]a[:]      # [1, 2, 3, 4, 5, 6, 7, 8]
a[:5]     # [1, 2, 3, 4, 5]
a[:-1]    # [1, 2, 3, 4, 5, 6, 7]
a[4:]     #             [5, 6, 7, 8]
a[-3:]    #                [6, 7, 8]
a[2:5]    #       [3, 4, 5]
a[2:-1]   #       [3, 4, 5, 6, 7]
a[-3:-1]  #                [6, 7]

切片可以正确处理超出列表边界的开始和结束索引。

1
2
first_twenty_items = a[:20]
last_twenty_items = a[-20:]

相反,直接访问同一索引将导致异常。

1
2
3
4
# a = [1, 2, 3, 4, 5, 6, 7, 8]
a[20]
>>>
IndexError: list index out of range

**注意:在某些情况下,切片会获得奇怪的结果。尝试 a[-0:]😅

1
2
>>>a[-0:]
>>>[1, 2, 3, 4, 5, 6, 7, 8]

切片列表的结果是一个全新的列表。保留了对原始列表中对象的引用。修改切片结果不会影响原始列表。

1
2
3
4
5
6
7
8
9
10
#a = [1, 2, 3, 4, 5, 6, 7, 8]
b = a[4:]
print ('before: ', b)
b[1] = 99
print ('after: ', b)
print ('no change: ', a)
>>>
before:    [5, 6, 7, 8]
after:     [5, 99, 7, 8]
no change: [1, 2, 3, 4, 5, 6, 7, 8]

在分配中使用时,切片将替换原始列表中的指定范围。切片分配的长度不必相同。该列表将增加或缩小以适应新的值。

1
2
3
4
5
6
7
#a = [1, 2, 3, 4, 5, 6, 7, 8]
print ('before: ', a)
a[2:7] = [99, 22, 14]
print ('after: ', a)
>>>
before: [1, 2, 3, 4, 5, 6, 7, 8]
after:  [1, 2, 99, 22, 14, 8]

使用切片,我们还可以创建列表的副本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> a
[1, 2, 3, 4, 5, 6, 7, 8]
>>> b = a[:]
>>> b is a
False
>>> b
[1, 2, 3, 4, 5, 6, 7, 8]>>> c = a
>>> c is a
True
>>> c
[1, 2, 3, 4, 5, 6, 7, 8]
>>> c.append(9)
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9]

在切片中指定“开始”,“结束”和“跨步”可用于反转列表。

1
2
3
4
# a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> b = a[::-1]
>>> b
[8, 7, 6, 5, 4, 3, 2, 1]

但是,除-1 以外的负数还有多少用处。考虑以下示例。

1
2
3
a        # [1, 2, 3, 4, 5, 6, 7, 8]
a[::2]   # [1, 3, 5, 7]
a[::-2]  # [8, 6, 4, 2]

在这里,:: 2表示选择从头开始的第二个项目,而::-2表示选择从末尾开始并向后移动的第二个项目。 仅当我们进行像2 :: 2-2 ::-2-2:2:-22:2:-2这样的切片时,它才会使事情复杂化

1
2
3
4
a[2::2]       # [3, 5, 7]
a[-2::-2]     # [7, 5, 3, 1]
a[-2:2:-2]    # [7, 5]
a[2:2:-2]     # []

切片语法的stride部分可能会造成混淆,尤其是在stride为负数的情况下。使用它可以使我们的代码难以维护。

小结

  1. 切片不仅可用于访问元素范围,而且还可用于或清除,撤消和复制列表。
  2. 尽可能避免将负的“跨步”与“开始”和“结束”索引一起使用。

以上代码在 python3.7 验证通过。

Rating: