647

In Python, calling e.g. temp = open(filename,'r').readlines() results in a list in which each element is a line from the file. However, these strings have a newline character at the end, which I don't want.

How can I get the data without the newlines?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Yotam
  • 9,789
  • 13
  • 47
  • 68
  • 8
    Use strip: `[l.strip('\n\r') for l in temp]`. Or even `rstrip`. And since iteration here it can be `in open` instead of `in temp`. – gorlum0 Sep 08 '12 at 13:03
  • 26
    I would be nice if in Python 3 there was a value to set open's `newline` argument to that chomped trailing newlines. – jxramos May 03 '17 at 21:21
  • 1
    Related: https://stackoverflow.com/questions/275018/how-can-i-remove-a-trailing-newline – AMC Feb 15 '20 at 00:38

14 Answers14

915

You can read the whole file and split lines using str.splitlines:

temp = file.read().splitlines()

Or you can strip the newline by hand:

temp = [line[:-1] for line in file]

Note: this last solution only works if the file ends with a newline, otherwise the last line will lose a character.

This assumption is true in most cases (especially for files created by text editors, which often do add an ending newline anyway).

If you want to avoid this you can add a newline at the end of file:

with open(the_file, 'r+') as f:
    f.seek(-1, 2)  # go at the end of the file
    if f.read(1) != '\n':
        # add missing newline if not already present
        f.write('\n')
        f.flush()
        f.seek(0)
    lines = [line[:-1] for line in f]

Or a simpler alternative is to strip the newline instead:

[line.rstrip('\n') for line in file]

Or even, although pretty unreadable:

[line[:-(line[-1] == '\n') or len(line)+1] for line in file]

Which exploits the fact that the return value of or isn't a boolean, but the object that was evaluated true or false.


The readlines method is actually equivalent to:

def readlines(self):
    lines = []
    for line in iter(self.readline, ''):
        lines.append(line)
    return lines

# or equivalently

def readlines(self):
    lines = []
    while True:
        line = self.readline()
        if not line:
            break
        lines.append(line)
    return lines

Since readline() keeps the newline also readlines() keeps it.

Note: for symmetry to readlines() the writelines() method does not add ending newlines, so f2.writelines(f.readlines()) produces an exact copy of f in f2.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • 2
    Note that ``[line.rstrip('\n') for line in file]`` will remove more than one trailing ``\n``. – Wes Turner Dec 31 '15 at 19:20
  • 1
    More simply, ``[line[:-(line[-1] == '\n') or len(line)+1] for line in file]`` could instead be ``[line[:-(line[-1] == '\n') or None] for line in file]``. – Wes Turner Dec 31 '15 at 19:25
  • 25
    These solutions read the entire file into memory. Changing the square brackets of a list comprehension to parentheses makes a generator expression which lets you iterate over the file one line at a time: `for line in (x.strip() for x in f):` – Joseph Sheedy Jan 20 '17 at 19:17
  • 4
    @velotron That's not really the point of the question/answer. Also: keep in mind that `with` closes the files when the block terminates, which means you cannot do `with open(...) as f: lines = (line for line in f)` and use `lines` outside the `with` because you'll get an I/O error. You can be lazy using a genexp, but you must consume it before closing the file. – Bakuriu Jan 20 '17 at 20:10
  • 2
    @WesTurner. But there won't be more than one trailing newline. The extra newline will be part of the next empty line – Mad Physicist Aug 22 '18 at 14:05
  • @MadPhysicist It's great if you have some assurance that the data validates before parsing it. – Wes Turner Aug 23 '18 at 16:28
  • A program that is supposed to read a file should never write to it. That's just bad practice. – Roland Illig May 01 '19 at 07:27
  • @Bakuriu I'm new to this. I understand how 'temp = open(filename,'r').readlines()' works (opens filename 'filename' for reading). Could you explain how 'temp = file.read().splitlines()' relates to the original filename 'filename'? – ndemarco Jul 13 '20 at 00:57
  • 1
    @ndemarco `file = open(filename)`. A `filename` is a string of characters that represent a filesystem resource "on disk". `open` reads that strings and returns the actual resource, most of the times a simple file. – Bakuriu Jul 13 '20 at 17:33
  • readline has to keep the newline or else how would you tell the difference between an empty line and the end of the file? – Eyal Jan 14 '21 at 03:51
  • Note: You can use a [generator *expression*](https://docs.python.org/3/reference/expressions.html#generator-expressions) to read text files incrementally line-by-line and remove the newlines from each one. For example: `with open(filename) as file:`, `for line in (line.rstrip() for line in file):` – martineau Mar 04 '22 at 12:45
  • The second option with iter is better when using 'rb' flag when opening the file. I had the case that a while loop and `if not line` did not work properly. `for line in iter(file.readline, b'')` worked for me then. – brillenheini Jun 20 '23 at 09:14
95
temp = open(filename,'r').read().split('\n')
Machavity
  • 30,841
  • 27
  • 92
  • 100
vivek
  • 4,951
  • 4
  • 25
  • 33
  • 15
    What would happen with `\r\n` newlines though? ;) – Wolph Sep 08 '12 at 12:11
  • @WoLpH Yes, I didn't take the platform specific newlines into account. It'll give the wrong thing. – vivek Sep 08 '12 at 12:16
  • 39
    Python automatically handles universal newlines, thus `.split('\n')` will split correctly, independently of the newline convention. It would matter if you read the file in binary mode.In that case `splitlines()` handles universal newlines while `split('\n')` doesn't. – Bakuriu Sep 08 '12 at 16:22
  • 8
    And there's always `os.linesep` :) – askewchan Sep 08 '16 at 17:50
  • @askewchan: That's true, but would it help? If the file you're reading contains the "wrong" line endings for your OS, `os.linesep` would be unhelpful. And if Bakuriu is right (I assume he is) that Python does the right thing magically (in text mode), then `os.linesep` is unnecessary. Still it does feel cleaner that `\n`. – LarsH Dec 01 '16 at 14:47
  • 1
    @LarsH, it would help in some circumstances, on my system `\r\n` line endings are _not_ converted to `\n`, whether read as text or binary, so `os.linesep` would work where `\n` does not. But `splitlines` is clearly the better choice, in the case you mention where the file does not match the os. Really I mostly mentioned it in case people looking at this discussion were unaware of its existence. – askewchan Dec 02 '16 at 02:51
  • 1
    @askewchan Maybe you're using an out of date version of Python. I believe that as of Python 3, universal newlines are enabled by default i.e. `\r\n` would be converted for text files even when you are running on Linux. – Arthur Tacca Mar 20 '17 at 13:30
  • 4
    `open()` [defaults to read mode](https://docs.python.org/3/library/functions.html#open). You don't have to pass `'r'`. – Boris Verkhovskiy Aug 22 '18 at 13:32
35

Reading file one row at the time. Removing unwanted chars from end of the string with str.rstrip(chars).

with open(filename, 'r') as fileobj:
    for row in fileobj:
        print(row.rstrip('\n'))

See also str.strip([chars]) and str.lstrip([chars]).

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
O-9
  • 1,626
  • 16
  • 15
  • 1
    The read mode is [the default mode](https://docs.python.org/3/library/functions.html#open). You don't have to pass the `'r'` explicitly. – Jeyekomon Feb 10 '22 at 10:08
23

I think this is the best option.

temp = [line.strip() for line in file.readlines()]
cieunteung
  • 1,725
  • 13
  • 16
RENZO
  • 255
  • 2
  • 5
  • 14
    This solution also removes leading and trailing spaces, which is not intended. – Roland Illig May 01 '19 at 07:30
  • 1
    The comprehension is really nice, though. At least with Python 3, one can use `temp = [line.rstrip() for line in file.readlines()]` to get what @Roland_Illig notes is intended. – bballdave025 Jan 11 '20 at 03:19
  • 1
    If you're going to iterate over all the lines, why do not so lazily? With `.readlines()`, you're effectively iterating over the entire file twice. – AMC Feb 15 '20 at 00:59
  • 3
    To be clear, the `readlines()` call is redundant, so this could be just `temp = [line.strip() for line in file]`. – jamesdlin Apr 19 '21 at 04:27
14
temp = open(filename,'r').read().splitlines()
Marcel
  • 2,810
  • 2
  • 26
  • 46
7

My preferred one-liner -- if you don't count from pathlib import Path :)

lines = Path(filename).read_text().splitlines()

This it auto-closes the file, no need for with open()...

Added in Python 3.5.

https://docs.python.org/3/library/pathlib.html#pathlib.Path.read_text

David Gilbertson
  • 4,219
  • 1
  • 26
  • 32
2

Try this:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  
SherylHohman
  • 16,580
  • 17
  • 88
  • 94
  • 5
    While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, as this reduces the readability of both the code and the explanations! – Blue Feb 05 '18 at 06:11
  • 2
    I don't see why anyone should use this over some of the alternative solutions. – AMC Feb 15 '20 at 01:00
  • 2
    This only works, if the file contains exactly one line. If the file contains many lines, it removes the information, where each line ended. – Kai Petzke Feb 17 '21 at 06:08
1

To get rid of trailing end-of-line (/n) characters and of empty list values (''), try:

f = open(path_sample, "r")
lines = [line.rstrip('\n') for line in f.readlines() if line.strip() != '']
YScharf
  • 1,638
  • 15
  • 20
1

You can read the file as a list easily using a list comprehension

with open("foo.txt", 'r') as f:
    lst = [row.rstrip('\n') for row in f]
marbel
  • 7,560
  • 6
  • 49
  • 68
0

Use pathlib.Path.read_text(), this opens the file in text mode, reads it and closes the file.

from pathlib import Path

temp = Path(filename).read_text()
user14534957
  • 336
  • 3
  • 10
0

If you still want to use readline(), you can strip the newline as you read each line. It seems both intuitive and seems to fit the python style (at least to me).

file = open("foo", "r")
aLineOfText = file.readLine().strip('\n')

Put this in a loop if you have to read multiple lines. This is a good work-around if the file is too big to be read into memory in one swoop.

SMBiggs
  • 11,034
  • 6
  • 68
  • 83
-2
my_file = open("first_file.txt", "r")
for line in my_file.readlines():
    if line[-1:] == "\n":
        print(line[:-1])
    else:
        print(line)
my_file.close() 
Necriss
  • 9
  • 1
  • 5
    Please add some explanation so that it will be useful to others. – samuellawrentz Aug 12 '18 at 14:46
  • 1
    You should use a context manager to handle the file object, and iterate over the file directly. By using `.readlines()` like this, you're effectively iterating over the entire file twice. – AMC Feb 15 '20 at 01:00
-2

This script here will take lines from file and save every line without newline with ,0 at the end in file2.

file = open("temp.txt", "+r")
file2 = open("res.txt", "+w")
for line in file:
    file2.writelines(f"{line.splitlines()[0]},0\n")
file2.close()

if you looked at line, this value is data\n, so we put splitlines()

to make it as an array and [0] to choose the only word data

-3
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])
srus
  • 319
  • 2
  • 8
  • 3
    But what if the line has a comma in it? – gilch Aug 19 '18 at 03:10
  • Strictly not a solution for the question, because of the comma glitch. But i gave it a upvote, as it a nice trix that i just used in a similar case, where i did `.split(',')` on all lines anyway – Otzen Jul 05 '23 at 11:50