str.splitlines()

Split a string into lines using universal newlines — the safer, cross-platform alternative to split("\n").

String methodPython 2.0+Live demo
Common call
for line in text.splitlines():
Returns
a list of lines; no empty tail even if text ends with a newline
Replaces
the split("\n") pattern that leaves a stray empty string at the end
Watch out
universal newlines — recognizes \n, \r, \r\n, plus rare separators
str.splitlines(keependskeependsIf True, keep the line terminator on each line. Useful for round-tripping — "".join(text.splitlines(True)) equals text.type: bool · default: False=False)
list[str]

Demo

Live evaluation
Try:
Inputs
stringstrthe source
keependsint1 = keep terminators, empty = strip
Output
'ab\\ncd\\nef'.splitlines()
['ab', 'cd', 'ef']

splitlines recognizes many line separators — \n, \r, \r\n, plus rarer ones like \x0b, \x0c, \x1c, \x1d, \x1e, \x85, \u2028, \u2029. Unlike split("\n"), a trailing newline does NOT produce a final empty string. When keepends=True, each line keeps the terminator that ended it — round-trippable back to the original.

Parameters

NameTypeRequiredDescription
keependsboolno (False)If True, keep the line terminator on each line. Useful for round-tripping — "".join(text.splitlines(True)) equals text.

Return value

list[str]A list of the lines. Line terminators are stripped by default; keepends=True keeps them attached. A trailing newline does NOT produce a final empty string.

Common patterns

Iterate lines from any text
The safe way to walk lines regardless of the source's line-ending convention.
for line in text.splitlines():
    process(line)
Round-trip preserving terminators
keepends=True keeps each line ending — useful for filtering without changing separators.
kept = [ln for ln in text.splitlines(True) if not ln.startswith("#")]
filtered = "".join(kept)
Normalize line endings
Split any convention, re-join with a single one.
normalized = "\n".join(text.splitlines())

Examples

1. Basic
"ab\ncd\nef".splitlines()
Returns
["ab", "cd", "ef"]
2. Trailing newline
"ab\ncd\n".splitlines()
Returns
["ab", "cd"] # no empty tail!
3. CRLF handled
"ab\r\ncd".splitlines()
Returns
["ab", "cd"]
4. Keep the terminators
"ab\ncd\n".splitlines(True)
Returns
["ab\n", "cd\n"]
5. Empty is empty
"".splitlines()
Returns
[]
6. No newline still gives one
"hello".splitlines()
Returns
["hello"]

Pitfalls

1. Different from split("\n") — no empty tail
split leaves an empty string after a trailing newline; splitlines does not. When reading files this is almost always what you want.
Empty at end
"a\nb\n".split("\n")
["a", "b", ""]
Clean list
"a\nb\n".splitlines()
["a", "b"]
2. Recognizes MORE than \n and \r\n
Universal newlines includes some obscure separators (\v, \f, \x1c-\x1e, U+0085, U+2028, U+2029). If your text contains those characters as data, they will be misidentified as line breaks.
Unexpected split
"ab\vcd".splitlines()
["ab", "cd"] # \v splits!
Explicit split
"ab\vcd".split("\n")
["ab\vcd"]
3. \r\n is one separator, not two
splitlines treats \r\n as a single line ending — no phantom empty lines on Windows-style text.
Wrong via split
"a\r\nb".split("\n")
["a\r", "b"] # stray \r attached
Right via splitlines
"a\r\nb".splitlines()
["a", "b"]
4. keepends round-trip needs join(""), not join("\n")
With keepends=True each line already carries its terminator; joining with "\n" adds a second one.
Doubled
"\n".join("a\nb\n".splitlines(True))
"a\n\nb\n" # extra blank line
Empty join
"".join("a\nb\n".splitlines(True))
"a\nb\n"

When to use

Use it
  • Reading lines from files or network text
  • Any text where line endings might vary
  • Round-trip-safe filtering (with keepends=True)
  • Normalizing mixed line endings
Reach for something else
  • You need the trailing empty string as a signal → split("\n")
  • You want to split on a DIFFERENT delimiter → split(delim)
  • You have obscure control characters as data → split("\n") is safer
  • Streaming very large text without loading all of it → iterate the file object

Notes

Complexity
O(n) — one linear scan
Return
A new list of strings
CPython impl
Objects/unicodeobject.c :: unicode_splitlines
Memory
One list plus one substring per line
Thread-safe
Yes — strings are immutable

FAQ

It treats a terminal line break as the terminator of the last line, not the start of a new empty line — matching how humans read text files. split("\n") does the opposite: any newline creates a boundary, so a trailing one leaves an empty tail.

History

2.0
splitlines() introduced.
3.0
Recognizes Unicode line separators U+2028 and U+2029 in addition to ASCII forms.