Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python crash course 8-10

Tags:

python

I'm currently reading Python Crash Course by Eric Matthes and doing some of the problem sets. One of them is giving me some difficulty and I was hoping someone could help me with it.

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 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.

And this is what I have for 8-9:

magician_names=['Alice', 'Alex', 'Blake']
def show_magicians(n):
    for magician in n:
        print (magician)

show_magicians(magician_names)

I just don't really know what to do for 8-10

like image 783
Alex McClead Avatar asked Aug 24 '26 22:08

Alex McClead


2 Answers

To do this, you can append to a string and reassign to add words to the end of each element:

magician += " the great"

Here, the += operator appends a string, then reassigns, which is equivalent to the following:

magician = magician + " the great"    

Now, you can add this to a function like so:

def make_great(list_magicians):
    for i in range(len(list_magicians)):
        list_magicians[i] += " the great"

make_great(magician_names)
show_magicians(magician_names)

The output is:

Alice the great
Alex the great
Blake the great

How this works is that we use a 'counter' for loop, similar to the ones in languages like C, (you can also use enumerate here), that loops through each element by using subscripts. Then it appends the string " the great" to all elements.


The reason why you cannot just do a simple for-in loop and modify those values is because for-in copies the value in the variable before in:

for magician in list_magicians: # magician is a temporary variable, does not hold actual reference to real elements

If they don't hold an actual reference, you cannot modify the reference, hence the reason you need to use counter loops to access the actual reference through subscript.

like image 72
Andrew Li Avatar answered Aug 27 '26 12:08

Andrew Li


The question asks you to modify magician_names. Since each entry in magician_names is a str, and strs are unmodifiable, you cannot simply modify each str in magician_names by appending " the great" to it. Instead, you need to replace each str in magician_names with its modified version.

So this seemingly straightforward approach:

def make_great(l):
    for name in l:
        name += " the great"

make_great(magician_names)

does not modify magician_names. It simply creates a new str object and assigns that to the name variable local to the for loop. Each element of magician_names is unchanged, i.e. it still points to the same str object.

But this approach:

def make_great(l):
    for index, name in enumerate(l):
        l[index] = name + " the great"

make_great(magician_names)

changes the str objects pointed to by magician_names and hence modifies magician_names as required.


To your comment,
for index, name in enumerate(l):
    l[index] = name + " the great"

is just the Pythonic way to write:

for index in range(len(l)):
    name = l[index]
    l[index] = name + " the great"

enumerate(l) returns an iterable (actually a lazy generator) that yields a matched index, element pair for each element in l.

like image 24
Craig Burgler Avatar answered Aug 27 '26 13:08

Craig Burgler