Post

【Python】Slice:被低估的小技巧,减少重复工作量

今天分享一个关于切片的简单技巧。

减少重复工作

先来看一个例子。

1
2
3
receipt1 = "物品1: 苹果 数量: 5  单价: 3.00元"
receipt2 = "物品2: 香蕉 数量: 10 单价: 2.00元"
receipt3 = "物品3: 橙子 数量: 3  单价: 5.00元"

这里有几个收据的字符串,需求是获取每个字符串的物品和价格。观察后可以发现,物品的索引总是 5 到 7,价格的索引总是 19 到 23,那我们可以这样写。

1
2
3
print(f'item: {receipt1[5:7]}, price: {receipt1[20:25]}')
print(f'item: {receipt2[5:7]}, price: {receipt2[20:25]}')
print(f'item: {receipt3[5:7]}, price: {receipt3[20:25]}')

但这样写存在不方便修改的问题,比如之后字符串的规范变动了,价格的索引变成了 20 到 24,那我就得重复修改这个索引。

1
2
3
4
5
6
receipt1 = "物品1: 苹果 数量: 5   单价: 3.00元"
receipt2 = "物品2: 香蕉 数量: 10  单价: 2.00元"
receipt3 = "物品3: 橙子 数量: 3   单价: 5.00元"
print(f'item: {receipt1[5:7]}, price: {receipt1[20:25]}')
print(f'item: {receipt2[5:7]}, price: {receipt2[20:25]}')
print(f'item: {receipt3[5:7]}, price: {receipt3[20:25]}')

定义 slice 对象可以很好地解决这个问题,我们来看看具体怎么写。

1
2
3
4
5
item_slice = slice(5,7)
price_slice = slice(20,25)
print(f'item: {receipt1[item_slice]}, price: {receipt1[price_slice]}')
print(f'item: {receipt2[item_slice]}, price: {receipt2[price_slice]}')
print(f'item: {receipt3[item_slice]}, price: {receipt3[price_slice]}')

通过 slice 关键字,并传入需要的索引,就可以定义一个切片对象。然后,再将原本放具体索引的地方改为放入 slice 对象就可以了。

这样,无论我要改成什么索引,都只需要在定义的地方稍微修改一下就可以了,不需要反复修改。

增强可读性

使用 slice 还有一个很大的优点,可以提升可读性。

比如这里写的 5 和 7,除了写代码的我们自己,其他人没法在第一眼就明白这个切片是什么意思。但如果我们使用了 slice 对象,别人一看就知道,啊这是一个获取 item 的切片。

用法

最后我想再稍微补充一下 slice 的使用方法。

slice 的传参机制和 range 一样,当传入一个参数时是 end,两个参数是 start 和 end,三个参数是 start, end, step。

这意味着,当我们想表达从某个索引开始切到最后一个时,用数字切片我们只需要 start 参数,将 end 留空。可如果使用 slice 对象,需要传入两个参数,并将第二个参数设为 None。

我们来看个例子帮助理解,对比一下这三种写法。

1
2
3
receipt1[5:]
receipt1[slice(5)]
receipt1[slice(5,None)]

同样,如果只需要使用 step,也要传入三个参数,并将前两个参数设为 None。

1
receipt1[slice(None, None, 2)]

最后

这是一个很简单的技巧,你可以在你的代码中试试看!

This post is licensed under CC BY 4.0 by the author.