3
\$\begingroup\$

For coding practice / interview exercises, I'd like to know if there's an optimizaton I can make to the following, where I "clean" a given word to remove punctuation or other characters that are not within "a" to "z".

There are some great answers here to remove punctuation from a string, so my question today is not the best way how to do this, but instead whether there is an optimization I can make to my 3 lines of code below in the word_count_engine function? Can I do this in 1 or 2 lines or make the code more efficient so it doesn't loop over the list twice (i.e. with 2 list comprehensions)?

def clean(word):
    returnword = ""
    for letter in word.lower():
        if letter >= 'a' and letter <='z':
            # not out of bounds
            returnword += letter
    return returnword


def word_count_engine(document):

    words = document.split() # if there are     extra    spaces, split() still filters empty words out FYI
    words = [clean(word) for word in words] # a word like "$33!" will result in an empty string though
    words = [word for word in words if word] # so filter out empty strings and get the final list of clean words

document = "Practice makes perfect. you'll only get Perfect by practice. just practice! $544 test"
\$\endgroup\$
6
\$\begingroup\$

Since Python strings are immutable, appending one character at a time using += is inefficient. You end up allocating a new string, copying all of the old string, then writing one character.

Instead, clean() should be written like this:

def clean(word):
    return ''.join(letter for letter in word.lower() if 'a' <= letter <= 'z')

Note that Python supports double-ended inequalities.

The name of your word_count_engine function poorly describes what it does. In fact, the function doesn't print or return anything, so it's all dead code. If I had to rewrite it, though, I'd say:

words = [word for word in map(clean, document.split()) if word]

Also consider replacing all of this code with a simple regular expression substitution.

\$\endgroup\$
  • \$\begingroup\$ Awesome, thanks! I learn more than I expect through Stack Exchange thanks to people like you! Re: name of function - sorry, it's because the function is actually for something more detailed than I have described, and the above lines are just the first few lines of the function. I should have made that clear in the question/renamed it. I'll practice with regex functions next. \$\endgroup\$ – rishijd Apr 5 '18 at 0:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.