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:-2
,2: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
为负数的情况下。使用它可以使我们的代码难以维护。
小结
- 切片不仅可用于访问元素范围,而且还可用于或清除,撤消和复制列表。
- 尽可能避免将负的“跨步”与“开始”和“结束”索引一起使用。
以上代码在 python3.7 验证通过。