amailia
amailia

Reputation: 11

Loop does not read first word as it does the others in a string

The goal of this is to censor the first string input, which will be a sentence, where the second string is a word to be censored. Given an input of censor("hey hey hey", "hey"), the result is "hey *** ***". I can't figure out why the first hey should be different from the other so that it doesn't get replaced. Any ideas?

def censor(text, word):
    text_list = []
    word_replace = []
    for char in word:
        word_replace.append('*')
    replace = ''.join(word_replace)
    for char in text:
    text_list = text.split()
    for key in text_list:
        str(key)
        if key == word:
            text_list.append(replace)
            text_list.remove(key)
    final = ' '.join(text_list)
    return final

Upvotes: 1

Views: 77

Answers (3)

John Coleman
John Coleman

Reputation: 51978

Your code can be made cleaner in a couple of ways. For one thing -- the * operator on strings is useful:

>>> 'hello' * 3
'hellohellohello'
>>>
>>> '*' * 3
'***'

You could perhaps use this to write a helper function that censors individual words. Something like:

def censorWord(candidate, word):
    if candidate == word:
        return '*' * len(word)
    else:
        return candidate

Typical output:

>>> censorWord("hey","hey")
'***'
>>> censorWord("hi", "hey")
'hi'

Also, in your code I would recommend constructing an entirely new list (say called censored_words) rather than trying to modify the given list. That way you can just append censored words constructed by repeatedly applying the censorWord function to the words in text_list and not worry about removing anything.

As you go deeper in Python you'll eventually be able to write functions like this in just a couple of lines (as in Samuel O'Malley's excellent answer), but it isn't a bad exercise to be able to first build up lists in a cleaner fashion.

Upvotes: 0

Samuel O'Malley
Samuel O'Malley

Reputation: 3541

If you are doing a lot of appends in a loop in Python it is a good sign that you should be using list comprehension or a generator expression instead.

It is also a very bad idea to be removing items from an array or list while iterating over it.

def censor(text, word):
    replacement_word = "*" * len(word)
    return " ".join(replacement_word if key == word else key for key in text.split())

Also please note that the best way to do this kind of thing is to use the builtin str.replace() method. Or even re.sub() if you need more control.

Upvotes: 0

Yu Hao
Yu Hao

Reputation: 122363

for key in text_list:
    #...
    text_list.append(replace)
    text_list.remove(key)

Here you are trying to modify text_list while iterating over it. Don't do that. The simple fix is to iterate over its copy:

for key in text_list[:]:

Upvotes: 2

Related Questions