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

Jinman Kim
Jinman Kim
5,586 Points

Bummer: AttributeError: 'str' object has no attribute 'remove'

Can anyone spot an error for me? Error code sounds like remove function not being supported? Do I need to import a specific library for that function?

disemvowel.py
def disemvowel(word):
    for letter in word:
        if letter.upper() == 'A':
            word.remove(letter)
        elif letter.upper() == 'E':
            word.remove(letter)
        elif letter.upper() == 'I':
            word.remove(letter)
        elif letter.upper() == 'O':
            word.remove(letter)
        elif letter.upper() == 'U':
            word.remove(letter)
    return word

disemvowel("hello")

2 Answers

Joao Cid
Joao Cid
7,706 Points

Hello Jinman Kim... Glad to help you. In fact, there's no "remove()" method for "str" type/objects... But, you can play with conversions from "str" to "list" and "list" to "str" (using the beautiful "join()" method of "str") and do it almost exactly as you have done it with your code, like the following:

def disemvowel(word):
    w_list = list(word)
    for letter in w_list.copy():
        if letter.upper() == 'A':
            w_list.remove(letter)
        elif letter.upper() == 'E':
            w_list.remove(letter)
        elif letter.upper() == 'I':
            w_list.remove(letter)
        elif letter.upper() == 'O':
            w_list.remove(letter)
        elif letter.upper() == 'U':
            w_list.remove(letter)
    return "".join(w_list)

print(disemvowel("hello"))

Nevertheless, try to figure out the following code:

def disemvowel(word):
    w_list = list(word)
    for letter in w_list.copy():
        if letter.upper() in  ['A', 'E', 'I', 'O', 'U']:
            w_list.remove(letter)
    return "".join(w_list)

I believe you can understand it fully, and agree that besides shorter, becomes much more expressive to read, right? Do not hesitate if further clarification needed... Keep safe, strong and always CODING!!! ;)

Jinman Kim
Jinman Kim
5,586 Points

Totally understood! Thanks for the clear explanation and much efficient code. Happy Coding!

Chris Freeman
Chris Freeman
Treehouse Moderator 68,423 Points

The code will not pass as is because it modifies the for-loop iterable. This should never be done. To fix this code, make a copy of the w_list to iterate over:

  • w_list.copy()
  • w_list[:] # slice notation you'll learn later

These can be used directly in the for statement.

Joao Cid
Joao Cid
7,706 Points

Absolutely right, Chris... I have missed the copy (either way you have mentioned). Sorry for that, Jinman Kim, I have edited the previous code in the meanwhile.