Python Crash Course 8-10
Solution 1:
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.
Solution 2:
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
.
Solution 3:
Okay, you already know how to iterate through the list. You want to make a similar function, where you modify the string referred to my magician
to say, "the Great".
So, if you had a string "Smedley" and you wanted to change that to a string "Smedley the Great" how would you do it?
update
So now that the answer's been given away anyway, there are a couple of other options that are more "functional" and arguably safer since you're protected from aliasing etc.
Option 1: create a new list, eg: (These examples done with iPython which is a very handy tool, worth installing for learning Python)
def make_great_1(lst):
rtn = []
for m in lst:
rtn.append(m+" the Great")
return rtn
In [7]: mages = [ 'Gandalf', 'Mickey' ]
In [8]: make_great_1(mages)
Out[8]: ['Gandalf the Great', 'Mickey the Great']
Option 2: use a list comprehension:
In [9]: [ mg+" the Great" for mg in mages ]
Out[9]: ['Gandalf the Great', 'Mickey the Great']
Now, the problem says to modify the list, and it's easy to imagine that means you should modify the strings, but in fact Python (unless you use a MutableString
) just makes a copy anyway. If you want to be really picky, either of these options could be re-done to assign the new list to mages
in my case, or magician_names
in yours.
Post a Comment for "Python Crash Course 8-10"