Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialGary Gibson
5,011 PointsWhy do I HAVE to make this substitution to get the code to run properly?
I'm working on a devowel program from Python Collections. In the first for loop, the new variable word_list is made equal list(word).
But why do I have to make this substitution?
I get that I have to set up a loop to look at each object in words (for word in words:), but word_list and list(word) contain the same things. But if I sub list(word) back in for word_list, the code doesn't execute anything below the first for loop.
Why?
words = [
"kookamunga",
"comatose"
]
vowels = list('aeiouAEIOU')
results = []
for word in words:
word_list = list(word)
for vowel in vowels:
while True:
try:
word_list.remove(vowel)
except:
break
results.append("".join(word_list))
for result in results:
print(result)
[MOD: added ```python formatting -cf]
words = [
"kookamunga",
"comatose"
]
vowels = list('aeiouAEIOU')
results = []
for word in words:
word_list = list(word)
for vowel in vowels:
while True:
try:
list(word).remove(vowel)
except:
break
results.append("".join(list(word)))
for result in results:
print(result)
5 Answers
Chris Freeman
Treehouse Moderator 68,441 PointsThe statement list(word)
returns a list based on word
. Because the returned object is not assigned to a variable it is not preserved, regardless of whether an item is removed.
Each time list(word)
is used, a fresh list is contructed. In the final join and print, the original word is still used.
When word_list
is used, the remove()
operates on the list "in place" updating word_list
at each iteration.
Gary Gibson
5,011 PointsI edited it as requested.
Gary Gibson
5,011 PointsHi again. I just noticed this same thing in effect in the Python Pop video.
the_list = ["a", 2, 3, 1, False, [1, 2, 3]]
print(the_list)
print((the_list.insert(0, the_list.pop(3))))
print((the_list)
This yields:
['a', 2, 3, 1, False, [1, 2, 3]]
None
[1, 'a', 2, 3, False, [1, 2, 3]]
In line 4 I try to print the list as I'm using insert and pop to save and remove and replant the 1. But all I get is "None". But the action is performed and when I try to print the_list in the next line, I see the result of the functions inside of print on line 3.
Chris Freeman
Treehouse Moderator 68,441 PointsHi Gary, It is confusing that some list methods return values while others operate on the list, changing it "in place" then return nothing (None
). The list method .insert()
operates on the list, and returns None
. So the print
operates on the return value of the expression, which is None
and not the list itself.
In is important to consult the docs or use help(list)
to verify how the method operations. From help(list)
, here are the list methods. The item after the "—>" indicates what is returned. If "None
" or not present, then "None
" is return from the statement.
$ python
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> help(list)
| append(...)
| L.append(object) -> None -- append object to end
|
| clear(...)
| L.clear() -> None -- remove all items from L
|
| copy(...)
| L.copy() -> list -- a shallow copy of L
|
| count(...)
| L.count(value) -> integer -- return number of occurrences of value
|
| extend(...)
| L.extend(iterable) -> None -- extend list by appending elements from the iterable
|
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value.
| Raises ValueError if the value is not present.
|
| insert(...)
| L.insert(index, object) -- insert object before index
|
| pop(...)
| L.pop([index]) -> item -- remove and return item at index (default last).
| Raises IndexError if list is empty or index is out of range.
|
| remove(...)
| L.remove(value) -> None -- remove first occurrence of value.
| Raises ValueError if the value is not present.
|
| reverse(...)
| L.reverse() -- reverse *IN PLACE*
|
| sort(...)
| L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
Gary Gibson
5,011 PointsThanks, Chris.
I see what you mean. But in this case, I can't seem to get the variable I assign to print. I keep getting "None."
my_list = [4, 6, 1, 3, 5, 2]
my_list.sort()
print(my_list)
my_sorted_list = my_list.sort()
print(my_sorted_list)
I don't understand why my_sorted_list returns None when I try to print it after I assigned it my_list.sort().
Chris Freeman
Treehouse Moderator 68,441 Pointssort()
operates on the list in place and does not return anything so my_list_sorted
will get None
.
After your first sort, my_list
is sorted. So then you would simply use
my_sorted_list = my_list
Keep in mind that this is a reference copy in that a change in either will affect both. To make an independent shallow copy use the slice indexing:
my_sorted_list = my_list[:]
By shallow, I mean if any item is my_list
is a container, only the top-level of that container is copied to a new object but the second level objects and deeper are not copied but instead will have the same object reference pointers inside. There is a "deep copy" available. If this last bit is too deep for now, it's ok to disregard for now.
Gary Gibson
5,011 PointsChrist, thanks again. It all became very clear with that last explanation.
The second part is a bit beyond me now, but it's cool!
Chris Freeman
Treehouse Moderator 68,441 PointsChris Freeman
Treehouse Moderator 68,441 PointsCan you comment in your code what substitution changes you mean?