views:

1379

answers:

6

I have some code in a python string that contains extraneous empty lines. I would like to remove all empty lines from the string. What's the most pythonic way to do this?

Note: I'm not looking for a general code re-formatter, just a quick one or two-liner.

Thanks!

+16  A: 

How about:

text = os.linesep.join([s for s in text.splitlines() if s])

where text is the string with the possible extraneous lines?

Lawrence Johnston
+1 to this for the use of splitlines(), which handles platform differences in line endings. Is there a benefit, though, to "if len(s)" as opposed to simply "if s"?
Jarret Hardie
Not that I know of. Just slipped my mind that Python treats empty strings as false. I just removed it.
Lawrence Johnston
len('\r\n') == 2 :) it's trickier than we expected
wuub
You're right about that one.
Lawrence Johnston
Use "if s.strip()" to treat whitespace as an "empty" line.
bpowah
You could remove the square brackets to use a generator expression instead of a list comprehension. Or do this: `'\n'.join(filter(None, text.splitlines()))` -- although I've always had mixed feelings about `filter(None, ..)`.
John Fouhy
text = os.linesep.join([s for s in text.splitlines() if s]) will handle platform differences in a better way
luc
You're right luc. Updated.
Lawrence Johnston
+5  A: 
"\n".join([s for s in code.split("\n") if s])

Edit2:

text = "".join([s for s in code.splitlines(True) if s.strip("\r\n")])

I think that's my final version. It should work well even with code mixing line endings. I don't think that line with spaces should be considered empty, but if so then simple s.strip() will do instead.

wuub
+1  A: 

This one will remove lines of spaces too.

re.replace(u'(?imu)^\s*\n', u'', code)

A: 

Suprised there's no love for the standard string replace method. But maybe it doesn't qualify as a one-liner, since it's just a plain old method call.

>>> manylines = 'hello\nworld\n!'
>>> print manylines
hello
world
!

>>> no_linefeeds = manylines.replace('\n', '')
>>> print no_linefeeds
helloworld!
monkut
Question wasn't to remove linefeeds, but to remove blank lines. ie: "\n\n", not "\n".
nilamo
+1  A: 
filter(None, code.splitlines())
filter(str.strip, code.splitlines())

are equivalent to

[s for s in code.splitlines() if s]
[s for s in code.splitlines() if s.strip()]

and might be useful for readability

ymv
A: 

And now for something completely different:

Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import string, re
>>> tidy = lambda s: string.join(filter(string.strip, re.split(r'[\r\n]+', s)), '\n')
>>> tidy('\r\n   \n\ra\n\n   b   \r\rc\n\n')
'a\012   b   \012c'

Episode 2:

This one doesn't work on 1.5 :-(

BUT not only does it handle universal newlines and blank lines, it also removes trailing whitespace (good idea when tidying up code lines IMHO) AND does a repair job if the last meaningful line is not terminated.

import re
tidy = lambda c: re.sub(
    r'(^\s*[\r\n]+|^\s*\Z)|(\s*\Z|\s*[\r\n]+)',
    lambda m: '\n' if m.lastindex == 2 else '',
    c)
John Machin