str.replace是如何工作的?

0 投票
2 回答
2922 浏览
提问于 2025-04-18 13:43

我有一个概念性的问题。我想把一个字符串里的标点符号去掉,所以我写了下面这个函数:

def nopunc(str):
    for x in string.punctuation:
        str = str.replace(x, " ")
    return str

这个方法有效。但是,当我稍微改了一下这个函数:

def nopunc(str):
    for x in string.punctuation:
        str1 = str.replace(x, " ")
    return str1

它就不管用了。我没有用 str = str.replace(x, ""),而是给这个字符串起了个新名字叫 str1。为什么这样会出问题呢?这和 .replace 有关系吗?

2 个回答

2

替换操作并不会改变str这个变量本身的值。实际上,是你用=这个赋值操作在改变它。

在第一种情况下,所有的替换都会叠加,因为每次用不同的标点符号进行替换时,都是在之前替换后的字符串上进行的。

而在第二种情况下,所有的替换都会被覆盖,因为每次用新的标点符号进行替换时,都是在那个(不变的)原始字符串上进行的,最后只返回最后一次的替换结果(就是把波浪线替换成空格)。

4

因为字符串是不可改变的,所以 str.replace(x, " ") 并不会对 str 这个字符串对象做任何修改。相反,它会返回一个新的字符串副本,在这个副本中,x 被替换成了 " "

在你的第一个循环中,每次循环都会把这个新创建的字符串对象赋值给已有的名字 str。所以,你的第一个函数实际上相当于:

def nopunc(str):
    str = str.replace(string.punctuation[0], " ")
    str = str.replace(string.punctuation[1], " ")
    str = str.replace(string.punctuation[2], " ")
    ...
    str = str.replace(string.punctuation[31], " ")
    return str

注意,名字 str 的值是不断更新的,这样就能保存任何的变化。

而第二个循环则只是不断地把名字 str1 重新赋值为 str.replace(x, " ")。这意味着你的第二个函数和这样做没有什么区别:

def nopunc(str):
    str1 = str.replace(string.punctuation[31], " ")
    return str1

撰写回答