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

Parimal Raghavan
PLUS
Parimal Raghavan
Courses Plus Student 1,940 Points

I need help on my Dewovel program!

Here's my code:

#make a list to hold the new words
new_inp=[]

#make a list of vowels
vowels=["a","e","i","o","u"]

#get a string of words, and convert in to a list of words
inp=input("Enter a list of words, seperated by commas: ")
inp=inp.split(",")
#conver the word into a list, and delete elements which are in the vowels list
for word in inp:
        (" ").strip(word)
    word=list(word)
    for letter in word:
        if letter in vowels:
            word.remove(letter)
        else:
            continue
    #capitalize the first letter of each word
    word[0]=word[0].upper()
    #turn word into a string
    "".join(word)
    new_inp.append(word)
#print the list
print(new_inp)

However, this works....stangely. If my input is apples, bananas, cherries, I get an output of [['P', 'p', 'l', 's'], [' ', 'b', 'n', 'n', 's'], [' ', 'c', 'h', 'r', 'r', 'e', 's']]. I'm pretty confused. Can anyone tell me where I went wrong?

2 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,441 Points

There were three items needing fixes. Modifying the iterable of a for loop changes the behavior. It is better to refer to a copy of word using [:]. The result of a str.join() needs to assign to a variable. The same for str.strip()

#make a list to hold the new words
new_inp=[]

#make a list of vowels
vowels=["a","e","i","o","u"]

#get a string of words, and convert in to a list of words
inp=input("Enter a list of words, seperated by commas: ")
inp=inp.split(",")
#conver the word into a list, and delete elements which are in the vowels list
for word in inp:
    # (" ").strip(word)
    word = word.strip()  # Fixed
    word=list(word)
    for letter in word[:]:  # Fixed
        if letter in vowels:
            word.remove(letter)
        else:
            continue
    #capitalize the first letter of each word
    word[0]=word[0].upper()
    #turn word into a string
    new_word = "".join(word)  # Fixed
    new_inp.append(new_word)
#print the list
print(new_inp)
Vittorio Somaschini
Vittorio Somaschini
33,371 Points

Hello Chris,

I was having a look at this conversations too.

Can you please explain me the difference between using the word list itself and the copy in the 2nd for loop? Using your code in a workspace I see that using the copy works just fine as you said, but if I use word itself, in the case of 2 straight vowels (like for example cherries or a mistyped banaanas), the output is not correct.

I have inserted a couple of print(word) statements to see the different between the 2 options but I can't understand this behavior.

Thanks Vittorio

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

It might be more instructive to add print(letter) statements.

As the for letter in word: loop runs, letter is assigned the next indexed value in word. When a letter is removed from word all the letter indexes shift. This makes the next letter assignment effectively skip a letter since it has become the same index as the loop just completed.

Look at this code:

word = list('banana')
for idx, l in enumerate(word):
    print(idx, l)
    if l in ['a', 'e', 'i', 'o', 'u']:
        word.remove(l)
        print('remove ' + l)

When each 'ais seen, it is removed from the word which shifts the next 'n into the position where the removed 'a' was. In the next iteration, `letter is assign the "next" letter which is now pointing to the 'a' after the shifted 'n':

0 b
1 a
remove a
2 a
remove a
3 a
remove a

The loop only runs 4 times.

By using the slice notation [:] to make a copy, the loop variables are independent of the contents of word as letters are removed.

word = list('banana')
for idx, l in enumerate(word[:]):
    print(idx, l)
    if l in ['a', 'e', 'i', 'o', 'u']:
        word.remove(l)
        print('remove ' + l)
0 b
1 a
remove a
2 n
3 a
remove a
4 n
5 a
remove a