我正在为具有 ansi 格式的字符串制作一个库,为了正确实现切片,我需要一个像这样的函数:
slicer(start, stop, step, string)
应该返回与string[start:stop:sep]
相同的输出,但不使用string[start:stop:step]
(允许使用string[i]
),它还需要以相同的方式处理start
、stop
和step
的负值就像字符串切片一样。
这是我到目前为止得到的代码,带有 # [?] 的部分是我不确定如何处理的部分
def slicer(start, stop, step, string):
if step == 0:
raise ValueError("Step can't be 0")
if step is None:
step = 1
if step > 0:
if start is None:
start = 0
elif start < 0:
# Ex:
# if s = "hello world"
# s[-4:] is the same as
# s[7:]
start += len(string)
if start < 0:
start = 0
if stop is None:
stop = len(string)
elif stop < 0:
stop += len(string)
if stop < 0:
stop = len(string)
# Negative step
else:
if start is None:
start = len(string) - 1
elif start < 0:
start += len(string)
if start < 0:
# [?]
if stop is None:
# [?]
elif stop < 0:
stop += len(string)
if stop < 0:
# [?]
n = ""
for i in range(start, stop, step):
n += string[i]
return n
让我困惑的是,当
stop
为负数时,step
的默认值应该是什么:
例如,
s = "hello world"
考虑 s[0::-1]
,这只是字符串的逆,dlrow olleh
,
现在,我该如何写这个而不省略停止值?,即 s[0:?:-1]
.
如果你尝试 0 你会得到
s[0:0:-1]
--> "dlrow olle"
,缺少“h”。
如果你尝试1,你会得到
s[0:1:-1]
--> "dlrow oll"
,缺少“呃”。
如果你尝试-1,你会得到
print(s[0:-1:-1]) --> ""
,这是一个空字符串
您可以使用
slice.indices
方法 (docs) 来获取与内置对象使用的索引相匹配的“标准化”索引。给定三个范围参数(非负、负或None
)和序列长度,您可以使用获得三个数字(非负
start
和
end
)
def slicer(start, stop, step, string):
start, stop, step = slice(start, stop, step).indices(len(string))
...
在您的情况下,请考虑首先传递字符串并为切片参数提供默认值,因为
step
不经常使用,因此使用默认 step=1
或 step=None
(两者是等效的),您的方法会更方便。
如果您打算将其用于
__getitem__
实现,您将已经获得一个 slice
对象,因此可以直接调用 .indices
。