Home > Blockchain >  Python: Modify a list from user-defined function
Python: Modify a list from user-defined function

Time:11-09

Python Crash Course (1st edition), by Eric MATTHES

Exercice 8-10 Great Magicians

"8-9. Magicians: Make a list of magician’s names. Pass the list to a function called show_magicians(), which prints the name of each magician in the list. 8-10. Great Magicians: Start with a copy of your program from Exercise 8-9. Write a function called make_great() that modifies the list of magicians by adding the phrase the Great to each magician’s name. Call show_magicians() to see that the list has actually been modified."

In the chapter, the author makes it quite clear that invoking a list as an argument in my defined function WILL modify said list (which is the goal, here). To the extent that, to avoid unwanted modifications to the original list, one should use as an argument to one's function "list[:]" instead of just list.

Well, modifying the list magicians in my function is precisely what I'm trying to do, through the following code. To no avail, so far. If anyone was so kind as to explain why, I would greatly appreciate it. Also, having just created a SO account for the occasion, I might be missing something about the etiquette, question-formatting or other idiosyncracies of the platform. Be sure to enlighten and correct me on these topics as you see fit.

Thanks in advance.

Code:

magicians = ["Danton", "Professor", "Fallon", "Tesla"]

def make_great(whocares):
    """making great"""
    for x in whocares:
        x = x   ", the Great"

make_great(magicians)
show_magicians(magicians) # The list magicians remained as it was: Why?

I did find a (heavy, ugly) way to fix it. Which looks more like a kludge than anything else: popping each original magician out of their magicians list, appending him (with the "Great" suffix) in a new temporary list, then plugging said new list with greatified magicians back into now empty original magicians list.

I can't help but feel this is missing the point of the exercice as it is designed: since the author was very explicit about how arguments magicians -allowing modifications to the list from within my make_great function- magicians[:] -building a copy, thus preventing modifications to the magicians list from make_great function- should be used, the exercice should be manageable without using a new list as a buffer.

CodePudding user response:

When you have

for x in whocares:
    x = x   ", the Great"

This gives the name x to the result of your addition, which is lost at each iteration of the loop!

This gives a somewhat dated, but great overview of what is happening
https://david.goodger.org/projects/pycon/2007/idiomatic/handout.html#python-has-names

Instead, build a new list or reassign the values directly to the original array

Packing a new array

results = []
for _ in _:
    results.append(...)
return results  # caller renames like mylist = function(mylist)

Modify list members via method

def my_function(my_list):
    for index in range(len(my_list)):
        my_list[index]  = ...  # mylist is updated

Assign to original list

def my_function(my_list):
    for index, value in enumerate(my_list.copy()):
        my_list[index] = value   ", the Great"
  • Related