Reputation: 169
I have a conceptual question. I was trying to get rid of the punctuations in a string, so I wrote the following function:
def nopunc(str):
for x in string.punctuation:
str = str.replace(x, " ")
return str
This worked. However, when I changed the function a little bit:
def nopunc(str):
for x in string.punctuation:
str1 = str.replace(x, " ")
return str1
it didn't work. Instead of having str = str.replace(x, "")
, I gave the string a new name called str1
. Why would that cause a problem? Does it have something to do with .replace
?
Upvotes: 0
Views: 3102
Reputation:
Because strings are immutable, str.replace(x, " ")
does not modify the string object referenced by str
in any way. Instead, it returns a copy of this object were x
is replaced with " "
.
In your first for-loop, every iteration assigns this newly created object to the existing name str
. So, your first function is basically equivalent to:
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
Notice how the value of the name str
is continually updated, thereby saving any changes.
The second for-loop however just repeatedly reassigns the name str1
to str.replace(x, " ")
. This means that your second function is no different than doing:
def nopunc(str):
str1 = str.replace(string.punctuation[31], " ")
return str1
Upvotes: 4
Reputation: 3913
Replace does not change the value held by str
. It is your =
assignment that does.
In the first case, all replacements add up, because each call with a different punctuation mark replaces stuff in the string resulting from the previous replacement.
In the second case, all replacements are lost because each call with a new punctuation mark replaces stuff in the (unchanging) original string, and only returns the last replacement (which is replacing tildes with spaces).
Upvotes: 2