Censor: help with replacing list items in iterations



I get error: 'Oops, try again. Your function fails on censor("hey hey hey","hey"). It returns "hey hey hey" when it should return "*** *** ***".'

I expected my code to break the string (text) into a list (newtext), and then iterate through each item and replace the item with ***'s if it matched (word). Unfortunately, for some reason I don't understand, it won't do that. Now, I have gotten the lesson to work if I switch to using the format newtext[newtext.index(i)] = "*" * len(word) instead of what appears below at line 8. However, I don't understand at all why that is any different from just using i.

Please explain for me!


P.S. You can remove the 'print' statements. I was just using them to see where the problem was occurring in my code.

def censor(text, word):
    newtext = text.split()
    print newtext
    for i in newtext:
        print i
        if i == word:
            print word
            i = "*" * len(word)
            print i
    return " ".join(newtext)
print censor("I love to eat birds with eat", "eat")


first problem is here,

yourf first line should prefferablty be an empty string variable so,

new_text = " "


I don't understand why that should be.

Doesn't .split() create a list, so why would I want to define that list with a predefined empty string variable?


The return value is unaltered from the its original definition. No censoring takes place. The screen output must be pretty crowded. Then the original prints.

Remove all the print statements from inside the function and concentrate on building the return object.

    result = []
    for item in newtext:
        if item == word:
            result.append("*" * len(word))
    return " ".join(result)

and now,

print censor("I love to eat birds with eat", "eat")    # I love to *** birds with ***


Okay so having removed the internal print statements, can I just get an explanation of why the return value is unaltered? Clearly the censoring "almost" takes place, in a sense, since it changes the items in newtext (within the for,in structure) to *** if they are matching the word. So why doesn't that change carry through into the return value?

I'm just trying to understand for the code below:

def censor(text, word):
    newtext = text.split()
    for i in newtext:
        if i == word:
            i = "*" * len(word)
    return " ".join(newtext)
print censor("I love to eat birds with eat", "eat")

on the fifth line why does
i = "*" * len(word)
not permeate the return value, when using the following statement instead does?
newtext[newtext.index(i)] = "*" * len(word)

It seems to me that they are essentially saying the same thing..


We cannot mutate the iterator variable in a look-up loop.


This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.