数据结构和算法-11-给切片命名

问题描述

假如我们的程序已经出现了一大堆已无法直视的硬编码切片下标,应该如何清理呢?

解决方案

假设我们有一段代码要从一个记录字符串中几个固定位置取出特定的数据字段

比如:

1
2
3
######    0123456789012345678901234567890123456789012345678901234567890'
record = '....................100 .......513.25 ..........'
cost = int(record[20:23]) * float(record[31:37])

上面切片的写法可读性非常差,如果给切片命个名,可读性就会强很多。

改进代码,使其可读性更好:

1
2
3
SHARES = slice(20, 23)  # 给切片命名
PRICE = slice(31, 37) # 给切片命名
cost = int(record[SHARES]) * float(record[PRICE]) # 使用命名的切片

扩展讨论

一般来讲,代码中如果出现大量的硬编码下标值会使得可读性和可维护性大大降低,给切片命名可以更加清晰的表达代码到底要做什么,可读性非常高。

内置的 slice() 函数创建了一个切片对象可以被用在任何切片允许使用的地方

比如:

1
2
3
4
5
6
7
8
9
10
11
12
>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4) # 给切片命名
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10,11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> del items[a]
>>> items
[0, 1, 4, 5, 6]

如果我们有一个切片对象 a,那么就可以分别调用它的 a.start , a.stop , a.step 属性来获取更多的信息。

比如:

1
2
3
4
5
6
7
8
>>> a = slice(5, 50, 2)
>>> a.start
5
>>> a.stop
50
>>> a.step
2
>>>

另外,我们还能通过调用切片的 indices(size) 方法将它映射到一个确定大小的序列上, 这个方法返回一个三元组 (start, stop, step)所有值都会被合适的缩小以满足边界限制, 从而使用的时候避免出现 IndexError 异常。

比如:

1
2
3
4
5
6
7
8
9
10
>>> s = 'HelloWorld'
>>> a.indices(len(s))
(5, 10, 2)
>>> for i in range(*a.indices(len(s))):
... print(s[i])
...
W
r
d
>>>
毕小烦 wechat
「请扫一扫上面的二维码,关注老毕的微信公众号」
「您的赞赏是老毕持续创作的动力」