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 trial

Python

Gary Gibson
Gary Gibson
5,011 Points

Why 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)
Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

Can you comment in your code what substitution changes you mean?

5 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,441 Points

The 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
Gary Gibson
5,011 Points

I edited it as requested.

Gary Gibson
Gary Gibson
5,011 Points

Hi 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
Chris Freeman
Treehouse Moderator 68,441 Points

Hi 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
Gary Gibson
5,011 Points

Thanks, 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
Chris Freeman
Treehouse Moderator 68,441 Points

sort() 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
Gary Gibson
5,011 Points

Christ, thanks again. It all became very clear with that last explanation.

The second part is a bit beyond me now, but it's cool!