Python readline() from a string?
Question:
In python, is there a built-in way to do a readline() on string? I have a large chunk of data and want to strip off just the first couple lines w/o doing split() on the whole string.
Hypothetical example:
def handleMessage(msg):
headerTo = msg.readline()
headerFrom= msg.readline()
sendMessage(headerTo,headerFrom,msg)
msg = "Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn"
handleMessage(msg)
I want this to result in:
sendMessage("Bob Smith", "Jane Doe", "Jane,nPlease order...")
I know it would be fairly easy to write a class that does this, but I’m looking for something built-in if possible.
EDIT: Python v2.7
Answers:
In Python 3, you can use io.StringIO:
>>> msg = "Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn"
>>> msg
'Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn'
>>>
>>> import io
>>> buf = io.StringIO(msg)
>>> buf.readline()
'Bob Smithn'
>>> buf.readline()
'Jane Doen'
>>> len(buf.read())
44
In Python 2, you can use StringIO (or cStringIO if performance is important):
>>> import StringIO
>>> buf = StringIO.StringIO(msg)
>>> buf.readline()
'Bob Smithn'
>>> buf.readline()
'Jane Doen'
Why not just only do as many splits as you need? Since you’re using all of the resulting parts (including the rest of the string), loading it into some other buffer object and then reading it back out again is probably going to be slower, not faster (plus the overhead of function calls).
If you want the first N
lines separated out, just do .split("n", N)
.
>>> foo = "ABCnDEFnGHInJKL"
>>> foo.split("n", 1)
['ABC', 'DEFnGHInJKL']
>>> foo.split("n", 2)
['ABC', 'DEF', 'GHInJKL']
So for your function:
def handleMessage(msg):
headerTo, headerFrom, msg = msg.split("n", 2)
sendMessage(headerTo,headerFrom,msg)
or if you really wanted to get fancy:
# either...
def handleMessage(msg):
sendMessage(*msg.split("n", 2))
# or just...
handleMessage = lambda msg: sendMessage(*msg.split("n", 2))
Do it like StringIO does it:
i = self.buf.find('n', self.pos)
So this means:
pos = msg.find("n")
first_line = msg[:pos]
...
Seems more elegant than using the whole StringIO…
The easiest way for both python 2 and 3 is using string’s method splitlines(). This returns a list of lines.
>>> "somenmultilenenstringn".splitlines()
[‘some’, ‘multilene’, ‘string’]
in Python string have method splitlines
msg = "Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn"
msg_splitlines = msg.splitlines()
headerTo = msg_splitlines[0]
headerFrom= msg_splitlines[1]
sendMessage(headerTo,headerFrom,msg)
In python, is there a built-in way to do a readline() on string? I have a large chunk of data and want to strip off just the first couple lines w/o doing split() on the whole string.
Hypothetical example:
def handleMessage(msg):
headerTo = msg.readline()
headerFrom= msg.readline()
sendMessage(headerTo,headerFrom,msg)
msg = "Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn"
handleMessage(msg)
I want this to result in:
sendMessage("Bob Smith", "Jane Doe", "Jane,nPlease order...")
I know it would be fairly easy to write a class that does this, but I’m looking for something built-in if possible.
EDIT: Python v2.7
In Python 3, you can use io.StringIO:
>>> msg = "Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn"
>>> msg
'Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn'
>>>
>>> import io
>>> buf = io.StringIO(msg)
>>> buf.readline()
'Bob Smithn'
>>> buf.readline()
'Jane Doen'
>>> len(buf.read())
44
In Python 2, you can use StringIO (or cStringIO if performance is important):
>>> import StringIO
>>> buf = StringIO.StringIO(msg)
>>> buf.readline()
'Bob Smithn'
>>> buf.readline()
'Jane Doen'
Why not just only do as many splits as you need? Since you’re using all of the resulting parts (including the rest of the string), loading it into some other buffer object and then reading it back out again is probably going to be slower, not faster (plus the overhead of function calls).
If you want the first N
lines separated out, just do .split("n", N)
.
>>> foo = "ABCnDEFnGHInJKL"
>>> foo.split("n", 1)
['ABC', 'DEFnGHInJKL']
>>> foo.split("n", 2)
['ABC', 'DEF', 'GHInJKL']
So for your function:
def handleMessage(msg):
headerTo, headerFrom, msg = msg.split("n", 2)
sendMessage(headerTo,headerFrom,msg)
or if you really wanted to get fancy:
# either...
def handleMessage(msg):
sendMessage(*msg.split("n", 2))
# or just...
handleMessage = lambda msg: sendMessage(*msg.split("n", 2))
Do it like StringIO does it:
i = self.buf.find('n', self.pos)
So this means:
pos = msg.find("n")
first_line = msg[:pos]
...
Seems more elegant than using the whole StringIO…
The easiest way for both python 2 and 3 is using string’s method splitlines(). This returns a list of lines.
>>> "somenmultilenenstringn".splitlines()
[‘some’, ‘multilene’, ‘string’]
in Python string have method splitlines
msg = "Bob SmithnJane DoenJane,nPlease order more widgetsnThanks,nBobn"
msg_splitlines = msg.splitlines()
headerTo = msg_splitlines[0]
headerFrom= msg_splitlines[1]
sendMessage(headerTo,headerFrom,msg)