【问题标题】:Is there a str.replace equivalent for sequence in general?一般来说,序列是否有等效的 str.replace ?
【发布时间】:2024-01-06 08:12:02
【问题描述】:

是否有类似于 str.replace 的方法可以执行以下操作:

>> replace(sequence=[0,1,3], old=[0,1], new=[1,2]) 
[1,2,3]

它应该真的像 str.replace :用另一个序列替换一个序列的“片段”,而不是用“新”的元素映射“旧”元素。 谢谢:)

【问题讨论】:

标签: python string python-3.x sequence str-replace


【解决方案1】:

不,恐怕没有内置函数可以做到这一点,但是您可以创建自己的!

步骤真的很简单,我们只需要在列表上滑动一个窗口,窗口的宽度是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-loop 会导致重新评估list 的替换部分,因此我更新了答案以改用while

【讨论】:

  • 我觉得你可以用seq[i:i+w] = new代替seq = seq[:i] + new + seq[i+w:]
  • This has problems with rescanning the replaced sections of the strings。 (此外,它在算法上效率低下,尽管很难在不消耗大量解释器开销的情况下实现更好的算法。)
  • @user2357112 感谢您指出这个问题,我现在重新写它:)
  • @user2357112 我已经更新了答案,它现在确实通过了您的测试用例,但可能还有其他错误 (:/)。您所说的“算法效率低下”是什么意思?您的意思是因为它正在重新评估被替换的部分吗?
  • @JoeIddon: Still not quite right. 它需要向前跳new 的长度,而不是old。我认为这是唯一剩下的错误,但我不确定。至于算法效率低下,此代码实现了一个简单的字符串搜索算法,花费 O(mn) 时间,其中 m = len(old) 和 n = len(seq)(不计算执行替换所花费的时间)。有algorithms that can do much better,但由于解释器开销,它们的 Python 实现可能不会在实践中获胜。
【解决方案2】:

我试过这个,但在使用这个方法之前阅读这个about eval() by Ned

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 的要求提供正确的输入。在您的示例中,序列中没有旧字符串。
  • 没有所谓的“正确输入”;答案应该不仅仅适用于问题中给出的特定示例输入。您的代码没有。
  • @user2357112 是的,但如果你正在为素数做一个程序,那么不要指望它会产生阶乘。检查OP的要求。序列中有旧的 int 数字,他想用新的 int 替换那些 int ,但在您的示例中,序列中没有旧的 int 。
  • @user2357112 立即结帐。
最近更新 更多