str.replace是如何工作的?
我有一个概念性的问题。我想把一个字符串里的标点符号去掉,所以我写了下面这个函数:
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