Tratando de modificar una lista en Python

Estoy leyendo el libro Python Crash Course de Eric Matthes, y estoy trabajando en este ejercicio:

8-9. Magos: Haz una lista de los nombres de los magos. Pase la lista a una función llamada show_magicians() , que imprime el nombre de cada mago en la lista.

8-10. Grandes magos: comience con una copia de su progtwig del ejercicio 8-9. Escriba una función llamada make_great() que modifica la lista de magos agregando la frase El Grande al nombre de cada mago. Llame a show_magicians() para ver que la lista se ha modificado realmente.

En su libro, modifica las listas pasándolas como argumentos en una función, y esa función cambia la lista, pero todo lo que obtengo es una lista de los nombres originales. ¿Qué hice mal?

 def show_magicians(magicians): for magician in magicians: print(magician.title()) def make_great(magicians): for magician in magicians: magician = "Great " + magician magicians = ['hermione','mihai','harry potter', 'voldemort'] make_great(magicians) show_magicians(magicians) 

Su función make_great no hace nada a la lista.

 def make_great(magicians): for magician in magicians: magician = "Great " + magician 

Tiene una variable local que cambia varias veces, pero nunca cambia la lista. En lugar:

 def make_great(magicians): for i in range(len(magicians)): magicians[i] = "Great " + magicians[i] 

Salida:

 Great Hermione Great Mihai Great Harry Potter Great Voldemort 

No puedes reasignar un elemento a la lista de esa manera. Cuando reasignas al magician en el bucle, todo lo que está haciendo es reasignar la variable local que se utiliza para referirse a una cadena en magicians .

Use una comprensión para crear una nueva lista que tenga “Genial” ante cada cadena; el cual devuelves

 def make_great(magicians): return ["Great " + magician for magician in magicians] magicians = ['hermione','mihai','harry potter', 'voldemort'] # Returned a new list to use great_magicians = make_great(magicians) print(great_magicians) # ['Great hermione', 'Great mihai', 'Great harry potter', 'Great voldemort'] 

Puede alterar las listas pasadas a las funciones:

 def f(my_list): my_list[0] = 2 l = [1, 2, 3] f(l) print(l) # [2, 2, 3] 

Y puede mutar los objetos en la lista mientras itera:

 def f(my_list): for l in my_list: l.append(9) l = [[], []] f(l) print(l) # [[9], [9]] 

Simplemente no puede hacer esto con objetos inmutables como cadenas, ya que los objetos inmutables no pueden alterarse de ninguna manera.

Como se respondió, su función no se modificó o en Python 3.6+, podría simplificar la función utilizando el formato f

 magicians = ['hermione','mihai','harry potter', 'voldemort'] def make_great(magicians): return [f'Great {i.title()}' for i in magicians] print(make_great(magicians))