1

I'm just new to python so dont understand much about it. PLease help me claryfying this:

names = ["Joey Tribbiani", "Monica Geller", "Chandler Bing", "Phoebe Buffay"]
print(names)
for name in names:
    name.lower().replace(' ','_')
print(names)

why doesn't it change the values in list names. I'm expecting below:

['joey_tribbiani', 'monica_geller', 'chandler_bing', 'phoebe_buffay']

This runs fine:

names = ["Joey Tribbiani", "Monica Geller", "Chandler Bing", "Phoebe Buffay"]
print(names)
names1=[]
for name in names:
    name1=name.lower().replace(' ','_')
    names1.append(name1)
print(names1)
pault
  • 41,343
  • 15
  • 107
  • 149
Jeet Singh
  • 303
  • 1
  • 2
  • 10
  • https://medium.com/@meghamohan/mutable-and-immutable-side-of-python-c2145cf72747 – chevybow Jul 17 '18 at 19:07
  • The problem is that you are changing current iterated value instead of the value of the list. You could try by using `for i in range(len(names))` and then using `names[i] = name.lower().replace(' ','_')` or you can use a comprehension to do it too. – lmiguelvargasf Jul 17 '18 at 19:09
  • @JeetSingh, was any of the answers useful for you, if so would you mind validating it? – lmiguelvargasf Jul 17 '18 at 19:52

2 Answers2

0

From the documentation of string.replace() (https://docs.python.org/2/library/string.html#string.replace):

Return a copy of string s with all occurrences of substring old replaced by new...

You need to store this copy somewhere, that's why your second example is working.

Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
0

The problem is that you are changing the item that you are getting from an iterator, and this item is an string which is a non-mutable object. When you call a method on a string it does not mutate (change), but a new string is returned instead.

When you run for item in items what you are basically calling is items.__iter__() which is equivalent to iter(items), and this will give you a copy of each elements of the list.

You have several alternatives to solve this issue, one as you mentioned is to create a new list and append the modified item. Another solution is tu use a list comprehension which is more Pythonic:

names = [name.lower().replace(' ', '_') for name in names]

You can also use a an index to replace the value in the list using the index as follows:

for i, name in enumerate(names):
    names[i] = name.lower().replace(' ','_')
lmiguelvargasf
  • 63,191
  • 45
  • 217
  • 228
  • I know there could be other answers, just wanted to confirm why the above code gives wrong results. Got the point. i'm getting string from the list which is non mutable. Thanks for the help! – Jeet Singh Jul 17 '18 at 19:22