Practice Makes Perfect 10/15: structure questions


#1

Hello!

I am a bit stuck on this one. Currently, my code is:

def censor(text, word):
  word = str(word)
  chunks = text.split(" ")
  #print chunks
  for item in chunks:
    if item == word:
      item = "*" * len(word)
  return chunks

#" ".join(chunks)

I get the following error message:

Your function fails on censor("hey hey hey","hey"). It returns "['hey', 'hey', 'hey']" when it should return "  *".

So I know the list is not falling through the loop, but I have no idea why that happens. I know the function is not complete, but why it is not even touching the list I cannot understand.

Also, when I leave the print and join statements uncommented, the system returns the following message:

Traceback (most recent call last):
  File "python", line 10, in <module>
NameError: name 'chunks' is not defined

But then proceeds to print one of the test arguments the system is passing (['the', 'password', 'is', 'spam']). How can it state that the variable is not defined, but at the same time print it?

This baffles me… :exploding_head:


#2

join is placed outside the function, chuncks has local scope, it only exists within the function

the problem with your code is that item will contain read-only values from your list, any changes made to it won’t persist, given in the next iteration of the loop python assigns the next value in list to item.


#3

Thanks!

So, the function creates it as a “work variable”, then deletes it after the work is done, or something like that?

Thanks as well for the take on the function itself, I guessed it was doing something like that (overwriting in each iteration of the loop). I continued working and got this:

def censor(text, word):
  word = str(word)
  chunks = text.split(" ")
  #print chunks
  censored = []
  for item in chunks:
    if item == word:
      item = "*" * len(word)
    censored.append(item)
  #print censored
  return " ".join(censored)

And it works!

Thanks again!


#4

the function doesn’t, the for loop does.

This isn’t actually how it works, but maybe it makes things clearer, lets do a manually for loop:

my_list = ['a', 'b', 'c']
item = my_list[0]
# code in the for loop would be here
item = "overwriting item"
# get next item in list
item = my_list[1]
# code in the for loop would be here

# get next item in list
item = my_list[2]

see? item = "overwriting item" would overwrite item, but then the next item in the list gets assigned to the variable, overwriting the value you gave it.


#5

Hm…

But in my case, the variable chunks was placed outside and before the for loop, which I tested by printing it before the loop began. How is the loop creating it before it starts itself?

As for how the loop overwrites the variable, your example is crystal clear as to how it works, but I still have the doubt as to why, in the exercise, it would take the string "hey hey hey", censored word "hey" and return "hey hey hey", instead of overwriting it three times with "***", or even with "hey" if the substituing part of the loop was not working, and returning a single "***" or "hey" as a result.

Sorry for so many weird questions. I guess the answers should be pretty obvious but I still don´t get it.


#6

it isn’t? chunks is the array which are looping over, item is the iterable which holds the values of the array, item is defined when you define the for loop:

for item in chunks:

item is the one thing being overwritten all the time, given the loop has to assign the next value to this variable


#7

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