-1
```python
#first way
def make_great(magicians):
    magicians = ['The Great '+ i for i in magicians]
    
#second way
def make_great2(magicians):
    for i in range(len(magicians)):
        magicians[i] = 'The great '+ magicians[i]
```

The original argument changed only by the second way.

ChadMeng
  • 1
  • 1
  • 1
    Because in `make_great` you are creating a new variable that also happens to be called `magicians` and replaces the one passed into the function. In `make_great2` you are modifying the existing variable `magicians` that is passed into the function. – rickdenhaan Sep 02 '21 at 14:36
  • 2
    Does this answer your question? [python; modifying list inside a function](https://stackoverflow.com/questions/22054698/python-modifying-list-inside-a-function) – Yevhen Kuzmovych Sep 02 '21 at 14:38
  • Now that the question was answered I'd like to give some small advice. If would be even better not to mutate the list at all but to create a new list and return it: `return [f'The great {magician}' for magician in magicians]` – Matthias Sep 02 '21 at 15:46
  • Thank you all, now I'm clear about how this mutation happens. – ChadMeng Sep 02 '21 at 16:07
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Sep 06 '21 at 08:51

3 Answers3

4

In python, variable names are used to refer to objects (such as a list, in your example). In your first way, you have created a new list object (using some data from the original), and set the variable "magician" to refer to this new object. But then the function ends, and this object isn't used anymore. You could make this method work by returning magicians, and then calling it as: great_magicians = make_great(names)

In contrast, your second way isn't creating a new list object. Instead, it is going to each individual place in the original list, and replacing each string with a new string. So when you are done, the original list has been modified.

Luke Nelson
  • 317
  • 2
  • 7
1

The first one does not mutate the passed list, but only rebinds the local variable magicians. You can make it a mutation by using slice assignment:

def make_great(magicians):
    magicians[:] = ['The Great ' + i for i in magicians]
user2390182
  • 72,016
  • 6
  • 67
  • 89
1

The first way creates a new list from the first but does not return the list so the new magicians list doesn't get out of the function and in the scope of the caller function, magicians is still the original list.

The second way mutates the list.

Jérôme
  • 13,328
  • 7
  • 56
  • 106