2
def onlyLetters(s):
    for i in range(len(s)):
        if s[i] == " ":
           s = s[:i] + s[i+1:]
           return s
        return s

Why is my above loop not working? It seems like it's only doing it once.

For example, if i have the string "Hello how are you", it's returning "Hellohow are you". I want it to check the string again and remove another space, and keep doing it until there are no spaces left. How do I fix this code?

4
  • 1
    How about your_string.replace(' ', '')? Commented Jan 31, 2017 at 7:25
  • 2
    Just remove return s from if condition. Commented Jan 31, 2017 at 7:27
  • 1
    Works for me if I remove the {return s} for the if condition Commented Jan 31, 2017 at 7:30
  • If I remove the first return s, it says "string index out of range" Commented Jan 31, 2017 at 7:35

9 Answers 9

4

Your code is stopping after the first space is replaced because you've told it to. You have return s inside the loop, and when that is reached, the rest of the loop is abandoned since the function exits. You should remove that line entirely.

There's another issue though, related to how you're indexing. When you iterate on range(len(s)) for your indexes, you're going to go to the length of the original string. If you've removed some spaces, however, those last few indexes will no longer be valid (since the modified string is shorter). Another similar issue will come up if there are two spaces in a row (as in "foo bar"). Your code will only be able to replace the first one. After the first space is removed, the second spaces will move up and be at the same index, but the loop will move on to the next index without seeing it.

You can fix this in two different ways. The easiest fix is to loop over the indexes in reverse order. Removing a space towards the end won't change the indexes of the earlier spaces, and the numerically smallest indexes will always be valid even as the string shrinks.

def onlyLetters(s):
    for i in range(len(s)-1, -1, -1): # loop in reverse order
        if s[i] == " ":
            s = s[:i] + s[i+1:]
    return s

The other approach is to abandon the for loop for the indexes and use a while loop while manually updating the index variable:

def onlyLetters(s):
    i = 0
    while i < len(s):
        if s[i] == " ":
            s = s[:i] + s[i+1:]
        else:
            i += 1
    return s
Sign up to request clarification or add additional context in comments.

13 Comments

after I remove the first return s, i get: IndexError: string index out of range
and this: ----> 3 if s[i] == " ":
The IndexError should only occur if you're looping in a forward direction. If you loop in reverse you won't have that problem.
The exception happens because your string gets shorter each time you remove a space. If you're iterating forwards, you keep going to the last indexes that don't exist any more. When iterating in reverse, you end with the smallest indexes which are always valid.
No, range(len(s)) only evaluates len(s) once and then creates a range object from it (or a list of values if you're using Python 2). For the reversed range, the range stops just before reaching -1, just like range(5) stops just before reaching 5.
|
2

just use python replace() method for Strings.

s.replace(" ","")

4 Comments

I can't use s.replace, I need to do it without any functions like that, only looping
problem with your code is the return method inside the if condition. It stops execution of the method after processing the first space. Remove it and you will be good to go.
thanks, but it's still not working, I'm getting an error: "string index out of range"
Ok I understood the problem. Check my answer
2

If you want to remove all spaces, use str.replace():

sentence = ' Freeman was here'
sentence.replace(" ", "")
>>> 'Freemanwashere'

If you want to remove leading and ending spaces, use str.strip():

sentence = ' Freeman was here'
sentence.strip()
>>> 'Freeman was here'

If you want to remove duplicated spaces, use str.split():

sentence = ' Freeman was here'
" ".join(sentence.split())
>>> 'Freemanwashere'

If you also want to remove all the other strange whitespace characters that exist in unicode you can use re.sub with the re.UNICODE arguement:

text = re.sub(r"\s+", "", text, flags=re.UNICODE)

or something like this,it's handles any whitespace characters that you're not thinking of 😉 :

>>> import re
>>> re.sub(r'\s+', '', 'Freeman was here')
'Freemanwashere'

if you don’t want to use anything like replace() or join() etc. you can do this :

def filter(input):
    for i in input:
        yield " " if i in " ,.?!;:" else i

def expand(input):
    for i in input:
        yield None if i == " " else object(), i

def uniq(input):
    last = object()
    for key, i in input:
        if key == last:
            continue
        yield key, i

def compact(input):
    for key, i in input:
        yield i

yourText = compact(uniq(expand(filter(input()))))

Comments

1

It's a little hard to tell, because the indentation in your example is hard to understand. But it looks to me like after you encounter and remove the very first space, you are returning s. So you only get a chance to remove one space before returning.

Try only returning s once you are out of the for loop.

Comments

1

You can do s.replace(" ", ""). This will take all your spaces (" ") and replace it by nothing (""), effectively removing the spaces.

1 Comment

can't use s.replace. I need to do it without that
0

You're returning the function after the first occurrence of a ",", which means it exits the loop and the function altogether. That's why it's only working for the first comma.

Comments

0

Try this,

def onlyLetters(s):
   length=len(s)
   i=0
   while(i<length):

      if s[i] == " ":
         s = s[:i] + s[i+1:]
         length=len(s)
      else
         i+=1

   return s

1 Comment

This won't work correctly if there are two or more spaces in a row.
0

If you want to use your own code only then try running this:

def onlyLetters(s):
    for i in range(len(s)):
        if s[i] == " ":
           s = s[:i] + s[i+1:]
    return s

or better you may use:

def onlyLetters(s):
    return s.replace(" ","")

3 Comments

Your return statement in the second code sample seems to be in completely the wrong place ...
Not really... str are immutable so you want to return s.replace(' ', '').
Well yes, you were correct. I made changes now. Thanks for the prompt response.
0
def remove_spaces(text):
    text_with_out_spaces='';
    while text!='':
        next_character=text[0];
        if next_character!=' ':
            text_with_out_spaces=text_with_out_spaces +next_character;
        text=text[1:];
    return text_with_out_spaces

print remove_spaces("Hi Azzam !! ?");

the output screenshot

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.