I'm confused about join and split methods

punctuation = ''' ,\/'-=[]{}/\!?*()%$#@^&_`"~''' + "" #+ ''''"''' (include only if string errors due to EOL)

def censor(text, word):
  text = text.lower()
  word = word.lower()
  text1 = str.split(' ', text)
  for x in text1:
    if x == word: 
    	word = "*" * len(word)
  print text1
censor("hello my friend", "hello")

It’s part of excercise 13.10 (I think it was; titled ‘practice makes perfect’)


Why u no work, code???


The join() method takes the instance string and applies it as a separator on the argument object to form a unified string.



'-'.join('SOS')               #  S-O-S

'---'.join(['...', '...'])    #  ...---...

split() is the inverse of join(), so takes a string object instance and applies the method to separate strings on the argument string.


'S-O-S'.split('-')            #   ['S', 'O', 'S']

'...---...'.split('---')      #  ['...', '...']

The class definition of the method is,


Where text is the string object and we want to split on space characters…

text.split(' ')

We have seen that join is a binding insertion method, and split is an unbinding extraction method.

join() will always produce a singular value, a string that can be bound to a variable as a singularity. split() will alwasys produce a pointer object with multiple references, each bound by their index in that object. So their are still bindings, only the original binding to the string has been broken.

When we think of bindings, it refers to the variable(s) that reference an object or value. If we think of a string as an object in memory, once we split it, we are no longer referencing that string, but the values we extracted from it, in the form of an indexed object, or pointer. We’ve created a derived iteratable from the original object.

This always messed me up at first. Tackle this part of the journey and world is your oyster.

punctuation = ''' ,\/'-=[]{}/\!?*()%$#@^&_`"~''' + "" #+ ''''"''' (include only if string errors due to EOL)

def censor(text, word):
  text = text.lower()
  word = word.lower()
  text1 = text.split(' ')
  for x in text1:
    if x == text1: 
      #trying to get length of element in text1 list
    	word = "*" * len(text1[int(word)])
      #how do I join while also replacing word in text?
    	text = word.join(text1)
  print text1
censor("hello my friend", "hello")

Read the comment tags, thanks.




Getting the length of an element in a list isn’t any different from looking up the element and passing it to len. Can’t get it to work? Do them separately at first then, and maybe you’re missing other information as well, like where in list that element is.

join doesn’t replace. But you can write code for replacing, and then join

Don’t try to solve everything at once. There’s a sequence of events that you need to happen. Start with the first thing you need to happen, use prints to show that you’ve got that something, then start on the next thing.

Don’t expect anything to snap into place and do the right thing, it’s up to you to get every single piece of information where you need it. You make it so, nothing else, and even when you believe you have made something happen, verify that it actually behaves that way by printing out what is being done like a log of events.

I think you might agree that if you have an output log of what’s happening, and you’re allowed to modify what’s happening at the location where something’s wrong in the log, then not a whole lot of mysteries will be able to hide in the code.


How do I do it separately?

All I can think of is x = len(word) * “*”

If x is an integer = len(word) then how do I convert that to a string of asterixes? Another loop?


There are some very obvious bugs in that code.
What you don’t need is for others to help you with the bugs themselves, what you need is to start observing what happens - because that’s the only way that they aren’t obvious, not looking.

Use print statements to print out what is happening.

If some part of the code does lots of things all at once, split it up so that you can wedge in some prints.


Yeah, I’m doing that


So, things like:

Here’s the original input:
here’s how long the bad word is
Here are the words in a list:
Iterating over those
is it supposed to be censored yes/no
what is the replacement?
did i successfully store the replacement?
is it supposed to be censored yes/no
what is the replacement?
did i successfully store the replacement?

finished the loop, here’s the final result that i’m about to present


Why does it say ‘List indices must be integers not string’

I’ve been able to compare strings before in a list.

['this', 'is', 'a', 'list', 'of', 'strings']

The strings are at index 0, 1, 2, 3, 4, and 5. At those indexes the elements all contain strings.


But I’m not using == comparison, but is comparison

Why am I not allowed to make string comparisons with if?


Please show us what you are not being allowed to do.


Here’s the output

hello my friend
['hello', 'my', 'friend']
Traceback (most recent call last):
  File "python", line 23, in <module>
  File "python", line 13, in censor
TypeError: list indices must be integers, not str
the password is spam
['the', 'password', 'is', 'spam']

And code

#punctuation = ''' ,\/'-=[]{}/\!?*()%$#@^&_`"~''' + "" #+ ''''"''' (include only if string errors due to EOL)

def censor(text, word):
  text = text.lower()
  print text
  word = word.lower()
  print word
  text1 = text.split(' ')
  print text1
  for x in text1:
    #print x
    #try to find out what position in the list text1 word is and match it to x in text
		if text1[x] is text1[word]: 
 			word = len(word)
			text1[word] = "*" * word
      #loop to try to get asterixes to equal len of word
      #while x < word +1:  
				#word += "*"
      #how do I join while also replacing word in text?
  print text
censor("Hello My friend", "Hello")


Printing is a step by step process. At a step in the process, print the running variable(s) of concern. Are we satisfied with the output? Comment the print and print after the next instruction. Use print in this way, rather than a catalog.


Indices is plural for index. Read the error message, when you agree with it, check where you might be doing otherwise. You already have the line so all that really remains is to check what the different names there refer to. Again, that comes down to printing out/observing what you’re doing

unrelated to the error message: is compares object identity. Not useful here.


What do you think it is I’m trying to find?


Well I gave up, guys. Thanks for the help!

I was considering subbing to codeacademy, but I don’t know if I want to pay for any of these services if the mods are going to be this helpful. Truly.

def censor(text, word):
    words = text.split()
    result = ''
    stars = '*' * len(word)
    count = 0
    for i in words:
    	if i == word:
        words[count] = stars
      count += 1
    result =' '.join(words)

    return result
print censor("this hack is wack hack", "hack")

There is honestly no way I could have come up with this solution. Also, it’s poorly indented, so the shell doesn’t even interpret it right.

The shell sucks anyway. It can’t even read blocks of code, since it’s always throwing indentation errors. Proof that it was poorly programmed.

Why should I even consider paying money to people that have a poorly programmed shell?


With a paid subscription you get a coach from CC. Mods here are voluteers and not on CC’s payroll. We try our best to not give away the answers but nudge the learner along.

From where did you get that solution? Could you not compare your code to it and resolve the issues that surface? That’s one way of spotting errors in our logic and execution, and fix them with a lesson learned.

As for indentation, we can take responsibility for that, right?

Given a text string such as a phrase, sentence or paragraph, find the target word and replace each character in it with a star (asterix). This is actually not very hard if we set out a plan and then write the code to carry it out.

text is a string value, meaning it has no binding to the outer scope so we can alter it with no effect.

text = text.split()

Now instead of being a sentence it is a list. Next we iterate over that list, one word at a time and compare it to the target. In simplest form we will look for only exact matches, without considering that 'hack' and 'Hack' are different, and only 'hack' will be censored.

The above code uses a counter to keep track of the index of each word.

text = text.split()
count = 0
for term in text:
    if term == word:
        text[count] = '*' * len(word)
    count += 1
return ' '.join(text)

The key to the above is very few moving parts and no extraneous variables. The less things to keep our eye on, the simpler it is to debug or modify.

Say we don’t want to use a counter but instead loop on the indices…

text = text.split()
for i in range(len(text)):
    if text[i] == word:
        text[i] = '*' * len(word)
return ' '.join(text)

or the even more explicit,

text = text.split()
for i, x in enumerate(text):
    if x == word:
        text[i] = '*' * len(word)
return ' '.join(text)

When we have mastered planning and execution in multiple forms we gain an appreciation of the algorithm process and the many variations available to arrive at the same outcome. Until then we cannot really begin to appreciate how built-ins work.

return text.replace(word, '*' * len(word))


Honestly, you guys should get paid for what you do.