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 Python Collections (2016, retired 2019) Lists Disemvowel

Disemvowel, loop skipping double vowels

Can anyone help me?

disemvowel.py
vowels = ["A", "E", "O", "I", "U"]

def disemvowel(word):
    word = list(word)
    word_copy = word
    for letter in word_copy:
        if letter.upper() in vowels:
            word.remove(letter)
    word = ''.join(word)
    return word

#looks fine, when I input for example "Warsaw" it outputs "Wrsw", but when I input "Warsaaw" it would give me "Wrsaw" 

Hi plejsyczejsy,

It looks like Nader has fixed your problem, but I thought I'd explain why it happens.

When the for loop is iterating through the word list, it's checking if each letter is a vowel. For your 'Warsaw' example above:

  • W (at index 0)
  • ^
  • is not a vowel
  • a (at index 1)
  • ^
  • is a vowel - this is removed

But before the for loop checks the list again, the list is moved 1 place, therefore the next letter checked is s not r. Therefore, in your original code, if you have two vowels side-by-side, this second vowel is skipped, because the for loop thinks it has already checked that index.

Does that make sense?

Nader Alharbi
Nader Alharbi
2,253 Points

Isn't that happening because you are pointing to the same list with two variables (not really creating two lists)?

Hey Nader,

Are you asking if the vowel skipping is caused by two variables looking at the same list? I don't think that's exactly true. As I understand it, the main issue is that the reference list the for loop iterates through checking for vowels, is the same list it's removing those vowels from. So when it removes a vowel, it thinks that index has already been checked, and so skips the following letter.

You're absolutely right that to avoid the above issue, you need to make a copy of the original list, and use that copy as your list to iterate through.

NB, if either of you didn't know, you can also copy a list to a new variable using [:]

new_list = old_list[:]
>>> def disemvowel(word):
    word = list(word)
    word_copy = word[:]
    for letter in word_copy:
        if letter.upper() in vowels:
            word.remove(letter)
    return ''.join(word)

>>> disemvowel('Warsaw')
'Wrsw'
>>> disemvowel('Warsaaw')
'Wrsw'
>>> 
Nader Alharbi
Nader Alharbi
2,253 Points

You are absolutely right! Thank you for explaining that.

1 Answer

Nader Alharbi
Nader Alharbi
2,253 Points

Hello there, Replace this code with the next one

word_copy = word
word_copy = word.copy()

Why is this happening? Honestly, i don't know :)

Nader Alharbi
Nader Alharbi
2,253 Points

Just tested this,

print(vowels)
print(vowels_2)

vowels_2.append("test")

print(vowels)
print(vowels_2)

Edit: Reason is explained by Ed H-P post.

Ohh, i didn't know i could do copy with this method. Thanks a lot!

Nader Alharbi
Nader Alharbi
2,253 Points

It was noted by Craig more than once and i did not give it much attention my self. Looks like he was right after all haha