Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How can I remove the first line of a multi-line string?

14,614 views
Skip to first unread message

Anthony Papillion

unread,
Sep 2, 2013, 12:06:30 PM9/2/13
to pytho...@python.org
Hello Everyone,

I have a multi-line string and I need to remove the very first line from
it. How can I do that? I looked at StringIO but I can't seem to figure
out how to properly use it to remove the first line. Basically, I want
to toss the first line but keep everything else. Can anyone put me on
the right path? I know it is probably easy but I'm still learning Python
and don't have all the string functions down yet.

Thanks,
Anthony

Chris “Kwpolska” Warrick

unread,
Sep 2, 2013, 12:12:35 PM9/2/13
to Anthony Papillion, pytho...@python.org
> --
> http://mail.python.org/mailman/listinfo/python-list

Use split() and join() methods of strings, along with slicing. Like this:

fullstring = """foo
bar
baz"""

sansfirstline = '\n'.join(fullstring.split('\n')[1:])

The last line does this:
1. fullstring.split('\n') turns it into a list of ['foo', 'bar', 'baz']
2. the [1:] slice removes the first element, making it ['bar', 'baz']
3. Finally, '\n'.join() turns the list into a string separated by
newlines ("""bar
baz""")

--
Chris “Kwpolska” Warrick <http://kwpolska.tk>
PGP: 5EAAEA16
stop html mail | always bottom-post | only UTF-8 makes sense

Oscar Benjamin

unread,
Sep 2, 2013, 12:18:26 PM9/2/13
to Anthony Papillion, Python List
On 2 September 2013 17:06, Anthony Papillion <papi...@gmail.com> wrote:
> Hello Everyone,
>
> I have a multi-line string and I need to remove the very first line from
> it. How can I do that? I looked at StringIO but I can't seem to figure
> out how to properly use it to remove the first line. Basically, I want
> to toss the first line but keep everything else. Can anyone put me on
> the right path? I know it is probably easy but I'm still learning Python
> and don't have all the string functions down yet.

>>> a = '''asd
... qwe
... rty'''
>>> print(a)
asd
qwe
rty
>>> a.splitlines()
['asd', 'qwe', 'rty']
>>> a.splitlines(True) # Keep the new lines
['asd\n', 'qwe\n', 'rty']
>>> a.splitlines(True)[1:] # remove first line
['qwe\n', 'rty']
>>> ''.join(a.splitlines(True)[1:]) # recombine
'qwe\nrty'
>>> a = ''.join(a.splitlines(True)[1:])
>>> print(a)
qwe
rty


Oscar

Anthony Papillion

unread,
Sep 2, 2013, 12:24:06 PM9/2/13
to Chris “Kwpolska” Warrick, pytho...@python.org
On 09/02/2013 11:12 AM, Chris “Kwpolska” Warrick wrote:
> On Mon, Sep 2, 2013 at 6:06 PM, Anthony Papillion <papi...@gmail.com> wrote:
>> Hello Everyone,
>>
>> I have a multi-line string and I need to remove the very first line from
>> it. How can I do that? I looked at StringIO but I can't seem to figure
>> out how to properly use it to remove the first line. Basically, I want
>> to toss the first line but keep everything else. Can anyone put me on
>> the right path? I know it is probably easy but I'm still learning Python
>> and don't have all the string functions down yet.
>>
>> Thanks,
>> Anthony
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>
> Use split() and join() methods of strings, along with slicing. Like this:
>
> fullstring = """foo
> bar
> baz"""
>
> sansfirstline = '\n'.join(fullstring.split('\n')[1:])
>
> The last line does this:
> 1. fullstring.split('\n') turns it into a list of ['foo', 'bar', 'baz']
> 2. the [1:] slice removes the first element, making it ['bar', 'baz']
> 3. Finally, '\n'.join() turns the list into a string separated by
> newlines ("""bar
> baz""")

This, of course, worked like a charm. I really need to study the string
methods. In the work I'm doing they are going to come in very handy.
Thank you, Chris!

Anthony


MRAB

unread,
Sep 2, 2013, 12:53:32 PM9/2/13
to pytho...@python.org
On 02/09/2013 17:12, Chris “Kwpolska” Warrick wrote:
> On Mon, Sep 2, 2013 at 6:06 PM, Anthony Papillion <papi...@gmail.com> wrote:
>> Hello Everyone,
>>
>> I have a multi-line string and I need to remove the very first line from
>> it. How can I do that? I looked at StringIO but I can't seem to figure
>> out how to properly use it to remove the first line. Basically, I want
>> to toss the first line but keep everything else. Can anyone put me on
>> the right path? I know it is probably easy but I'm still learning Python
>> and don't have all the string functions down yet.
>>
>> Thanks,
>> Anthony
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>
> Use split() and join() methods of strings, along with slicing. Like this:
>
> fullstring = """foo
> bar
> baz"""
>
> sansfirstline = '\n'.join(fullstring.split('\n')[1:])
>
> The last line does this:
> 1. fullstring.split('\n') turns it into a list of ['foo', 'bar', 'baz']
> 2. the [1:] slice removes the first element, making it ['bar', 'baz']
> 3. Finally, '\n'.join() turns the list into a string separated by
> newlines ("""bar
> baz""")
>
Another way is to use .partition:

>>> fullstring = """foo\nbar\nbaz"""
>>> fullstring.partition("\n")[2]
'bar\nbaz'

Roy Smith

unread,
Sep 2, 2013, 1:07:11 PM9/2/13
to
In article <mailman.500.13781390...@python.org>,
Let me toss out a couple of other possibilities. Not necessarily
better, but if you're learning about strings, you might as well learn
some other ways to do it:


s = """foo

bar

baz"""

print "using index..."
i = s.index('\n')
print s[i+1:]

print "using regex..."
import re
print re.sub(r'^[^\n]*\n', '', s)


I'll admit, the split/slice/join solution is probably the easiest to
implement (and to understand when you're reading the code). But, it
copies all the data twice; once when split() runs, and again when join()
runs. Both the index and regex solutions should only do a single copy.
For huge strings, this might matter. For a three-liner as in your
example, it doesn't make any difference.

Vlastimil Brom

unread,
Sep 2, 2013, 1:18:36 PM9/2/13
to python
2013/9/2 Anthony Papillion <papi...@gmail.com>:
> Hello Everyone,
>
> I have a multi-line string and I need to remove the very first line from
> it. How can I do that? I looked at StringIO but I can't seem to figure
> out how to properly use it to remove the first line. Basically, I want
> to toss the first line but keep everything else. Can anyone put me on
> the right path? I know it is probably easy but I'm still learning Python
> and don't have all the string functions down yet.
>
> Thanks,
> Anthony
> --
> http://mail.python.org/mailman/listinfo/python-list

Hi,
it is probably not worth it for such simple replacement, but just to
add another possibility to the already mentioned methods - you can use
regular expression replacement:

>>> import re
>>> re.sub(r"^.*\n", "", "abc\ndef\nghi")
'def\nghi'
>>>


hth,
vbr

Terry Reedy

unread,
Sep 2, 2013, 6:19:17 PM9/2/13
to pytho...@python.org
On 9/2/2013 12:06 PM, Anthony Papillion wrote:

> I have a multi-line string and I need to remove the very first line from
> it. How can I do that? I looked at StringIO but I can't seem to figure
> out how to properly use it to remove the first line. Basically, I want
> to toss the first line but keep everything else. Can anyone put me on
> the right path? I know it is probably easy but I'm still learning Python
> and don't have all the string functions down yet.

Simply splitting off the first line, using the maxsplit parameter, is
more efficient that splitting all lines and joining all but the first. I
presume you also want to remove a single line without \n to split on.

def keeprest(s):
try:
return s.split('\n', 1)[1]
except IndexError:
return ''

for s in ('', 'a', 'a\n', 'a\nrest\n'):
print('for', repr(s), 'kept:', repr(keeprest(s)))
>>>
for '' kept: ''
for 'a' kept: ''
for 'a\n' kept: ''
for 'a\nrest\n' kept: 'rest\n'

MRAB's s.partition('\n')[2] has exactly the same result as keeprest(s)
as, by design, it handles the no-separator case and always returns a
triple. I believe it is the equivalent (in C for CPython) of

def partition(self, string, splitter):
try:
first, rest = string.split(splitter, maxsplit=1)
return (first, splitter, rest)
except ValueError: # from impossible assignment of 1 item to 2 names
return (string, '', '')

---

If you have *any* iterable of lines and want to process the first line
differently than the rest (including just ignoring it), you can use

first = True:
for line in lines:
if first:
process_first(line)
first = False
else:
process_rest(line)

*or*

it = iter(sometext)
try:
first = next(it)
except StopIteration: # always catch this with explicit next
pass

At this point, *it* now represents the rest of the text and you can pass
it to any function expecting an iterable of lines.

--
Terry Jan Reedy

Fábio Santos

unread,
Sep 11, 2013, 8:08:18 AM9/11/13
to Roy Smith, pytho...@python.org

Is there not a limit argument to str.split? This should be trivial.

first, rest = multiline_str.split('\n', 1)

Terry Reedy

unread,
Sep 11, 2013, 8:42:54 AM9/11/13
to pytho...@python.org
On 9/11/2013 8:08 AM, Fábio Santos wrote:

> Is there not a limit argument to str.split? This should be trivial.

Yes, I posted an example using it the first day.

I also showed how to use iter and next with files and avoid copying.

> first, rest = multiline_str.split('\n', 1)

This does not work right is there is no '\n'

Then someone pointed out
first, dummy, rest = partition('\n')
which does work with no '\n'

--
Terry Jan Reedy


Roy Smith

unread,
Sep 11, 2013, 9:03:27 AM9/11/13
to
In article <mailman.244.1378901...@python.org>,
Fábio Santos <fabiosa...@gmail.com> wrote:

One suggested solution:
> > > > sansfirstline = '\n'.join(fullstring.split('\n')[1:])

To which I suggested a couple of alternatives:
> > i = s.index('\n')
> > print s[i+1:]
> > [...]
> > print re.sub(r'^[^\n]*\n', '', s)


> > I'll admit, the split/slice/join solution is probably the easiest to
> > implement (and to understand when you're reading the code). But, it
> > copies all the data twice; once when split() runs, and again when join()
> > runs. Both the index and regex solutions should only do a single copy.
> > For huge strings, this might matter. For a three-liner as in your
> > example, it doesn't make any difference.
> >
>
> Is there not a limit argument to str.split? This should be trivial.
>
> first, rest = multiline_str.split('\n', 1)

This certainly prevents the extra splitting and re-compositing of the
additional lines.

One thing to watch out for is that split(s, 1) does *at most* 1 split.
If the original string didn't have any newlines, you would end up with a
single-item list and the unpack would fail. You can get around that
with:

rest = multiline_str.split('\n', 1)[-1]

but that's kind of cryptic.

Looking back at my solutions suggested above, s.index() fails in the
same situation (throws ValueError). The regex solution works fine, once
again proving that 1970's technology is still superior to all this
newfangled stuff.

A coworker recently introduced me to what is apparently a classic essay
(http://www.team.net/mjb/hawg.html). If Unix is the Hole Hawg of
operating systems, then regexes are the Hole Hawg of string processing
tools. Those of us who grew up around them, appreciate their power and
have learned how to use them without chopping off any fingers. And we
look on with a mix of amusement and pity at the current crop of
programmers who play with index(), split(), startswith(), rpartition(),
etc and think they're using real tools :-)

For the record, I have never used a Hole Hawg. I do, however, own a
Milwaukee 1/2" drill. Which also comes with the screw-in handle for
two-handed operation. I've had that get away from me a couple of times,
so I figure it's about my limit. Torque is a wonderful thing until the
thing you're drilling into weighs more than you do.

sga...@gmail.com

unread,
Dec 15, 2015, 7:42:57 PM12/15/15
to
On Monday, September 2, 2013 at 11:53:32 AM UTC-5, MRAB wrote:
> On 02/09/2013 17:12, Chris "Kwpolska" Warrick wrote:
I realize this is very old, but thanks for posting this reply. I like this answer the best.

wxjm...@gmail.com

unread,
Dec 16, 2015, 3:51:09 AM12/16/15
to
>>> s = """abc
... αβγ
... абв"""
>>> i = 0
>>> ns = ''
>>> while i < len(s):
... if s[i] == '\n':
... break
... i += 1
...
>>> i += 1
>>> while i < len(s):
... ns += s[i]
... i += 1
...
>>> print(ns)
αβγ
абв

Steven D'Aprano

unread,
Dec 16, 2015, 5:19:13 AM12/16/15
to
On Wed, 16 Dec 2015 11:42 am, sga...@gmail.com wrote:

> On Monday, September 2, 2013 at 11:53:32 AM UTC-5, MRAB wrote:
>> On 02/09/2013 17:12, Chris "Kwpolska" Warrick wrote:
>> > On Mon, Sep 2, 2013 at 6:06 PM, Anthony Papillion <papillion [at]
>> > gmail.com> wrote:
>> >> Hello Everyone,
>> >>
>> >> I have a multi-line string and I need to remove the very first line
>> >> from it. How can I do that? I looked at StringIO but I can't seem to
>> >> figure out how to properly use it to remove the first line. Basically,
>> >> I want
>> >> to toss the first line but keep everything else.

The maxsplit parameter to str.split makes this easier than falling off a
greased log:


py> astring = """Hello world,
... How are things?
... Hope you are well.
... Goodbye.
... """
py> astring.split("\n", 1)[1]
'How are things?\nHope you are well.\nGoodbye.\n'



--
Steven

0 new messages