467

In Python, calling

temp = open(filename,'r').readlines()

results in a list in which each element is a line in the file. It's a little stupid but still: readlines() also writes newline character to each element, something I do not wish to happen.

How can I avoid it?

martineau
  • 99,260
  • 22
  • 139
  • 249
Yotam
  • 7,564
  • 13
  • 42
  • 66
  • 4
    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
  • 14
    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
  • Related: https://stackoverflow.com/questions/275018/how-can-i-remove-a-trailing-newline – AMC Feb 15 '20 at 00:38

9 Answers9

686

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
  • 7,044
  • 6
  • 62
  • 63
Bakuriu
  • 85,459
  • 18
  • 168
  • 202
  • 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
  • 13
    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
  • 3
    @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
  • 1
    @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
54
temp = open(filename,'r').read().split('\n')
vivek
  • 4,039
  • 4
  • 22
  • 32
  • 14
    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
  • 31
    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
  • @askewchan: Good to know! – LarsH Dec 02 '16 at 11:42
  • 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
  • 1
    `open()` [defaults to read mode](https://docs.python.org/3/library/functions.html#open). You don't have to pass `'r'`. – Boris Aug 22 '18 at 13:32
  • When is the file closed? – Roland Illig May 01 '19 at 07:31
20

another example:

Reading file one row at the time. Removing unwanted chars with from end of the string 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])

(python >= 2.0)

pushkin
  • 7,514
  • 14
  • 41
  • 74
O-9
  • 931
  • 9
  • 13
12
temp = open(filename,'r').read().splitlines()
Marcel
  • 2,175
  • 2
  • 19
  • 36
11

I think this is the best option.

temp = [line.strip() for line in file.readlines()]
cieunteung
  • 1,265
  • 7
  • 12
RENZO
  • 135
  • 1
  • 5
  • 9
    This solution also removes leading and trailing spaces, which is not intended. – Roland Illig May 01 '19 at 07:30
  • 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
  • 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
2

Try this:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  
SherylHohman
  • 12,507
  • 16
  • 70
  • 78
  • 4
    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! – Goodbye StackExchange Feb 05 '18 at 06:11
  • 1
    I don't see why anyone should use this over some of the alternative solutions. – AMC Feb 15 '20 at 01:00
  • 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
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
  • 11
  • 1
  • 3
    Please add some explanation so that it will be useful to others. – samuellawrentz Aug 12 '18 at 14:46
  • 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
-3
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])
srus
  • 311
  • 2
  • 8
-8
def getText():
    file=open("ex1.txt","r");

    names=file.read().split("\n");
    for x,word in enumerate(names):
        if(len(word)>=20):
            return 0;
            print "length of ",word,"is over 20"
            break;
        if(x==20):
            return 0;
            break;
    else:
        return names;


def show(names):
    for word in names:
        len_set=len(set(word))
        print word," ",len_set


for i in range(1):

    names=getText();
    if(names!=0):
        show(names);
    else:
        break;
Pang
  • 8,605
  • 144
  • 77
  • 113