如何制作python字符串切片克隆功能?

How to make a python string slicing clone function?

提问人:user316108 提问时间:9/8/2023 更新时间:9/9/2023 访问量:60

问:

我正在制作一个带有 ansi 格式的字符串库,为了正确实现切片,我需要一个这样的函数:它应该返回与 相同的输出,但不使用 ( 是允许的),它还需要处理 的负值,并且与字符串切片的方式相同。slicer(start, stop, step, string)string[start:stop:sep]string[start:stop:step]string[i]startstopstep

这是我到目前为止得到的代码,带有# [?]的部分是我不确定如何处理的部分

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

让我感到困惑的事情与默认值应该是多少有关: 例如,考虑 ,这只是字符串 , 的倒数, 现在,如何在不省略停止值的情况下编写此内容?stopsteps = "hello world"s[0::-1]dlrow ollehs[0:?:-1]

如果你尝试 0,你会得到

s[0:0:-1] --> "dlrow olle",它缺少“h”。

如果你尝试 1 你得到

s[0:1:-1] --> "dlrow oll",它缺少“嗯”。

如果你尝试 -1,你会得到

print(s[0:-1:-1]) --> "",它是一个空字符串

Python 字符串 算法 切片

评论

2赞 user2357112 9/8/2023
“为了正确实现切片,我需要一个这样的函数:slicer(start, stop, step, string) 它应该返回与 string[start:stop:sep] 相同的输出,但不使用 string[start:stop:step]” - 为什么不直接切片字符串?
0赞 user2357112 9/8/2023
“让我感到困惑的是,当步长为负数时,停止的默认值应该是多少”——你的函数的所有参数都是必需的。您不必担心默认值。
0赞 user316108 9/8/2023
带有 ansi 的字符串有类似 \033[91;中间 1m,切片时不应将其视为字符串的一部分,因此用于库的对象结构需要这样的函数
0赞 user316108 9/8/2023
@user2357112,这个函数只是一个需要相同逻辑的更简单的示例,在实际代码中,它实际上是一个类的 getItem dunder 方法,我需要在其中处理默认值。
1赞 STerliakov 9/8/2023
(并且是 ,不是 。如果你想要反转的字符串,它等同于 or 而不是别的,除非你知道字符串长度,否则它的扩展形式将是'hello'[0::-1]'h''olleh''hello'[::-1]'hello'[None:None:-1]'hello'[-1::-1]'hello'[-1:-len('hello')-1:-1])

答:

1赞 STerliakov 9/9/2023 #1

您可以使用方法 (docs) 获取与内置对象使用的索引相匹配的“规范化”索引。给定三个范围参数(非负数、负数或)和一个序列长度,您可以使用以下命令获得三个数字(非负数和)slice.indicesNonestartend

def slicer(start, stop, step, string):
    start, stop, step = slice(start, stop, step).indices(len(string))
    ...

在你的例子中,考虑先传递字符串,并为切片参数提供默认值,因为不经常使用,所以你的方法使用 default or 会更方便(两者都是等效的)。stepstep=1step=None

如果你打算用它来实现,你会得到一个对象,所以可以直接调用它。__getitem__slice.indices