5

While answering this question I had a doubt regarding how to reduce multiple spaces in a string to one in Python without using regex. Say the string is as follows:

s = "Mary    had    a little lamb"

The first solution that came to my mind was

' '.join(s.split())

But this will not conserve leading and trailing spaces if the string was something like

s = "    Mary    had    a little lamb  "

In order to conserve leading and trailing spaces (if present), I came up with a slightly different approach where I added a dummy character to the starting and ending of the string (in this case a '-') which I later removed after the split. The code is as follows:

' '.join(('-' + s + '-').split())[1:-1]

Is there any other built in function or another pythonic way to do this?

Edit: By conserving leading and trailing spaces, I meant that in case there are multiple spaces at the beginning and/or at the end of the string, these multiple spaces should also be reduced to a single space

3
  • 3
    I liked your solution. Other than that I'd go with a regex. Though yours definitely requires a comment, a regex might not. Commented Jan 11, 2014 at 14:34
  • when I try your solution with the dummy characters, it doesn't conserve the leading/trailing whitespace, I don't understand.. Commented Jan 11, 2014 at 15:29
  • @Totem, A correction: The solution that I mentioned would reduce multiple spaces at the beginning and/or at the end of the string to a single space. It will not conserve all the spaces Commented Jan 11, 2014 at 16:31

5 Answers 5

3

You could use something like:

from itertools import groupby

s = "    Mary    had    a little lamb  "
res = ''.join(' ' if is_space else ''.join(chars) for is_space, chars in groupby(s, str.isspace))
#  Mary had a little lamb 
Sign up to request clarification or add additional context in comments.

2 Comments

I was just writing this up, although I decided against str.isspace because that would pick up tabs too.
@DSM yes... I was being lazy... although... lambda ch: ch == ' ' is not really much more effort :p
0

You can use reduce:

>>> reduce(lambda x, y: x if x[-1]==' ' and y==' ' else x+y, s) if s else ''
' Mary had a little lamb '

2 Comments

Hi alexander, I'm using python3.3 seems like reduce() is not present in 3.x version
@Pulimon It is moved to functools in Python3: from functools import reduce
0
>>> s = "    Mary    had    a little lamb  "
>>> s
'    Mary had a little lamb  '
>>> len0 = len(s)
>>> s = s.rstrip()
>>> len1 = len(s)
>>> s = s.lstrip()
>>> s = " ".join(s.split())
>>> print s
Mary had a little lamb
>>> s = s.rjust(len1).ljust(len0)
>>> s
'    Mary had a little lamb  '

This code will preserve spaces. I know it's not required, but I'll just leave this here.

1 Comment

Hi loa_in_: By leading and trailing spaces I meant that if there are multiple spaces at the beginning or at the end of a string, those multiple spaces should also be reduced to a single space. In this solution you conserve all the spaces
0

This appears to be fine for me.

test_str = "    Mary    had    a little lamb  "
while "  " in test_str:
    test_str = test_str.replace("  ", " ")

print test_str # yield ' Mary had a little lamb '

Comments

0

(len(s) - len(s.lstrip()) * ' ' + ' '.join(s.lstrip().rstrip().split()) + (len(s) - len(s.rstrip()) * ' '

1 Comment

This doesn't preserve leading and trailing spaces, as OP asked for in the question.

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.