是否有一个适用于序列的str.replace等效方法?

4
有没有一种类似于str.replace的方法可以做到以下功能:
>> replace(sequence=[0,1,3], old=[0,1], new=[1,2]) 
[1,2,3]

它应该像str.replace一样运作:用另一个序列替换序列的“一部分”,而不是将“旧”的元素映射为“新”的元素。谢谢 :)

1
如果有的话,那很可能就在 itertools 模块中。 - Barmar
1
请查看此答案 https://dev59.com/fmcs5IYBdhLWcg3wYy9T#12898180 - Omar Einea
2
没有。 - juanpa.arrivillaga
2个回答

4
很抱歉,没有内置函数可以做到这一点,但是您可以自己创建一个!这些步骤非常简单,我们只需要在列表上滑动一个窗口,其中窗口的宽度为 len(old)。在每个位置,我们检查窗口是否等于 old,如果是,我们就在窗口前面切片,插入 new,并将剩余的 list 连接到后面 - 这可以通过直接分配给 old 切片来完成,正如 @OmarEinea 所指出的那样。
def replace(seq, old, new):
    seq = seq[:]
    w = len(old)
    i = 0
    while i < len(seq) - w + 1:
        if seq[i:i+w] == old:
            seq[i:i+w] = new
            i += len(new)
        else:
            i += 1
    return seq

有一些测试表明它可以正常工作:

>>> replace([0, 1, 3], [0, 1], [1, 2])
[1, 2, 3]
>>> replace([0, 1, 3, 0], [0, 1], [1, 2])
[1, 2, 3, 0]
>>> replace([0, 1, 3, 0, 1], [0, 1], [7, 8])
[7, 8, 3, 7, 8]
>>> replace([1, 2, 3, 4, 5], [1, 2, 3], [1, 1, 2, 3])
[1, 1, 2, 3, 4, 5]
>>> replace([1, 2, 1, 2], [1, 2], [3])
[3, 3]

正如@user2357112所指出的,使用for循环会导致重新评估list中被替换的部分,因此我更新了答案,改用while循环


我认为你可以使用seq[i:i+w] = new代替seq = seq[:i] + new + seq[i+w:] - Omar Einea
1
这段代码存在替换字符串后重新扫描的问题(https://ideone.com/y2Rcks)。此外,它的算法效率较低,尽管实现更好的算法而不会增加解释器开销是困难的。 - user2357112
1
@user2357112 谢谢您指出那个问题,我现在会重写它 :) - Joe Iddon
@user2357112,我已经更新了答案,现在它可以通过你的测试用例,但可能还有其他问题(:/)。你所说的“算法效率低下”是什么意思?你是不是指因为它重新评估了替换部分? - Joe Iddon
@user2357112感谢您提供的指针信息,尝试使用C编写该算法并查看实际变化将会很有趣。我也会阅读那篇维基百科文章,因为它看起来很不错 :) - Joe Iddon
显示剩余2条评论

-1

我尝试过这个方法,但在使用之前请阅读Ned关于eval()的文章

import re
import ast

def replace(sequence, old, new):
    sequence = str(sequence)
    replace_s=str(str(old).replace('[', '').replace(']', ''))
    if '.' in replace_s:
        replace_ss=list(replace_s)
        for j,i in enumerate(replace_ss):
            if i=='.':
                try:
                    replace_ss[0]=r"\b"+ replace_ss[0]
                    replace_ss[j]=r".\b"
                except IndexError:
                    pass
        replace_s="".join(replace_ss)


    else:

        replace_s = r"\b" + replace_s + r"\b"


    final_ = str(new).replace('[', '').replace(']', '')
    return ast.literal_eval(re.sub(replace_s, final_, sequence))





print(replace([0, 1, 3], [0, 1], [1, 2]))

输出:

[1, 2, 3]

@user2357112,请按照 OP 的要求提供正确的输入。在您的示例中,序列中没有旧字符串。 - Aaditya Ura
没有所谓的“正确输入”; 答案应该适用于不仅仅是问题中给出的特定示例输入。但你的代码并没有做到这一点。 - user2357112
如果我们在sequence中加入old列表的实例,它并不会神奇地开始工作。 - user2357112
@user2357112 现在去看看。 - Aaditya Ura
@user2357112 等待下一个 ;) - Aaditya Ura
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接