0

Modifying a list in a Function

Hi as per I know, any changes made to the list inside the function’s body are permanent. But below code is not working properly. I want to modify each item of the list to ‘Great harry’, ‘Great ron’, ‘Great hermione’ But when I print it, it’s just harry, ron, hermione. Could you please help me? def make_great(magicians_names) : for magicians_name in magicians_names : magicians_name = 'Great ' + magicians_name def show_magicians(magicians_names) : for magicians_name in magicians_names: print(magicians_name.title()) magicians_names = ['harry', 'ron', 'hermione'] make_great(magicians_names) show_magicians(magicians_names)

29th Jan 2019, 10:57 AM
Lucy Lee
Lucy Lee - avatar
13 Answers
+ 2
First the solution - explanation in a second. :) def make_great(k): return ['Great ' + i for i in k] def show_magicians(v): for name in v: print(name.title()) list_a = ['harry', 'ron', 'hermione'] list_b=make_great(list_a[:]) print("Origianal One") show_magicians(list_a) print("\n'Great' added one") show_magicians(list_b)
30th Jan 2019, 1:22 PM
HonFu
HonFu - avatar
+ 4
You are changing magicians_name, not the item in your list. You can use this pattern instead: For i in range(len(your_list)-1): your_list[i] = 'Great ' + your_list[i] Alternatively if you like: your_list = ['Great '+name for name in your_list]
29th Jan 2019, 11:11 AM
HonFu
HonFu - avatar
+ 3
A function is like a separate work unit: They get a task, do the job, and after the job is done, everything that happened in the function is erased. In order to use a value in your main code, you need to *return* the result from the function. Then, if you call the function, you can imagine it like this: f() will be exchanged to whatever you returned And what you return, you can store, like every other value. So you write: x = f() And that will become: x = whatever the function returned And after this, you can use x however you like. In the example of your code, you pass a copy of your list and return from the function the 'enhanced' version. And then you just do with it whatever you want. Let me add one thing: In this case you could even just pass the original list_a, because the list comprehension creates a new list anyway.
30th Jan 2019, 1:27 PM
HonFu
HonFu - avatar
+ 2
Thank you so much! but I think it should be for i in range(len(list)) not ‘-1’ cause when I did, ‘Great’ is not added to the last item Thank you :)
29th Jan 2019, 10:32 PM
Lucy Lee
Lucy Lee - avatar
+ 1
Lucy Lee, ha, you're right, I messed that up, sorry! 😅 Good that it works now.
29th Jan 2019, 10:37 PM
HonFu
HonFu - avatar
+ 1
HonFu Thank you so much! I’ve been studying this langues for 4 days and still there are lots of things I need to learn haha Your advice really helped me!!! Thank you so much again!!!!
31st Jan 2019, 12:02 AM
Lucy Lee
Lucy Lee - avatar
0
HonFu Can I aske you one more question? What it I want to make a copy of the list of ‘Great’ added one, and keep the original one as unchanged? I did it as below, and both are same result. Just magicians name without ‘Great’ show_magicians(magicians_names[:]) show_magicians(magicians_names)
30th Jan 2019, 12:16 AM
Lucy Lee
Lucy Lee - avatar
0
I hope I understand you correctly: You don't want to change the original list but create a copy of it with modified items? For example: list_b = [] for item in list_a: list_b.append('Great '+item) Or alternatively: list_b = ['Great '+item for item in list_a] If you create this copy in your function, you can return the copy: return list_b And you call the function while already preparing a vessel for the product: my_new_list = that_function(old_list)
30th Jan 2019, 12:22 AM
HonFu
HonFu - avatar
0
HonFu Yes you understood me correctly :) But can’t I make this work using below? function(list[:]) Cause this book wants me to use that and I have no idea what I’m doing wrong....
30th Jan 2019, 12:34 AM
Lucy Lee
Lucy Lee - avatar
0
The problem is that by passing list[:] as an argument, you create a new, nameless object. This object will be properly modified by your function; but afterwards it will be 'forgotten' since you aren't referencing it anywhere. You can make a named copy first, then pass it to the function. list_b = list_a[:] function(list_b) Now your copy has a name and after you change it in your function, you can still refer to it. Or you pass the original list to the function and make the copy inside of it: def f(list_): copy = list_[:] # you do stuff with copy return copy new_list = f(old_list)
30th Jan 2019, 1:14 AM
HonFu
HonFu - avatar
0
HonFu so I think I can’t use ‘list[:]’ as an argument. This book is confusing... Thanks for your advice! :)
30th Jan 2019, 2:00 AM
Lucy Lee
Lucy Lee - avatar
0
Yes, you can use list[:] as an argument; you just have to remember that list[:] is a *copy* of list and not list itself, so if the function doesn't store or return the result somehow, it will be lost. Imagine you open a text file in a text editor. Then you copypaste the text into a new, empty document. You can work with the copy without worrying about the original file; but if you forget to 'save as' the text in the end, all your work will have been in vain.
30th Jan 2019, 4:44 AM
HonFu
HonFu - avatar
0
HonFu Hmmm I really want to understand this part..... Can you advise me what I’m doing wrong in the code below...? def make_great(k): for i in k : list_b = ['Great ' + i for i in k] def show_magicians(v): for name in v: print(name.title()) list_a = ['harry', 'ron', 'hermione'] make_great(list_a[:]) print("Origianal One") show_magicians(list_a) print("\n'Great' added one") show_magicians(list_a[:])
30th Jan 2019, 12:38 PM
Lucy Lee
Lucy Lee - avatar