Bagaimana cara membaca file tanpa baris baru?

374

Dengan Python, menelepon

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

menghasilkan daftar di mana setiap elemen adalah baris dalam file. Agak bodoh tapi tetap saja: readlines()juga menulis karakter baris baru untuk setiap elemen, sesuatu yang saya tidak ingin terjadi.

Bagaimana saya bisa menghindarinya?

Yotam
sumber
4
Gunakan jalur: [l.strip('\n\r') for l in temp]. Atau bahkan rstrip. Dan karena iterasi di sini bisa in openbukan in temp.
gorlum0
11
Saya akan senang jika dalam Python 3 ada nilai untuk mengatur newlineargumen terbuka untuk baris baru yang dikompilasi itu.
jxramos

Jawaban:

555

Anda dapat membaca seluruh file dan membagi baris menggunakan str.splitlines:

temp = file.read().splitlines()

Atau Anda dapat menghapus baris baru dengan tangan:

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

Catatan: solusi terakhir ini hanya berfungsi jika file diakhiri dengan baris baru, jika tidak baris terakhir akan kehilangan satu karakter.

Asumsi ini benar dalam kebanyakan kasus (terutama untuk file yang dibuat oleh editor teks, yang sering melakukan menambahkan baris baru berakhir pula).

Jika Anda ingin menghindari ini, Anda dapat menambahkan baris baru di akhir 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]

Atau alternatif yang lebih sederhana adalah ke stripbaris baru sebagai gantinya:

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

Atau bahkan, meskipun sangat tidak terbaca:

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

Yang mengeksploitasi fakta bahwa nilai balik orbukan boolean, tetapi objek yang dievaluasi benar atau salah.


The readlinesMetode ini sebenarnya setara dengan:

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

Karena readline()menyimpan baris baru juga readlines()menyimpannya.

Catatan: untuk simetri ke readlines()dalam writelines()metode tidak tidak menambahkan berakhir baris, sehingga f2.writelines(f.readlines())menghasilkan salinan dari fdalam f2.

Bakuriu
sumber
1
Perhatikan bahwa [line.rstrip('\n') for line in file]akan menghapus lebih dari satu trailing \n.
Wes Turner
1
Lebih sederhana, [line[:-(line[-1] == '\n') or len(line)+1] for line in file]bisa jadi malah [line[:-(line[-1] == '\n') or None] for line in file].
Wes Turner
10
Solusi ini membaca seluruh file ke dalam memori. Mengubah tanda kurung siku dari pemahaman daftar menjadi tanda kurung membuat ekspresi generator yang memungkinkan Anda mengulangi file satu baris pada satu waktu: for line in (x.strip() for x in f):
Joseph Sheedy
2
@velotron Sebenarnya bukan itu inti dari pertanyaan / jawaban. Juga: perlu diingat bahwa withmenutup file ketika blok berakhir, yang berarti Anda tidak dapat melakukan with open(...) as f: lines = (line for line in f)dan menggunakan di linesluar withkarena Anda akan mendapatkan kesalahan I / O. Anda bisa malas menggunakan genexp, tetapi Anda harus mengkonsumsinya sebelum menutup file.
Bakuriu
@WesTurner. Tetapi tidak akan ada lebih dari satu baris baru. Baris baru tambahan akan menjadi bagian dari baris kosong berikutnya
Gila Fisikawan
38
temp = open(filename,'r').read().split('\n')
vivek
sumber
14
Apa yang akan terjadi dengan \r\nbaris baru? ;)
Wolph
26
Python secara otomatis menangani baris baru universal, sehingga .split('\n')akan terpecah dengan benar, terlepas dari konvensi baris baru. Akan menjadi masalah jika Anda membaca file dalam mode biner. Dalam hal ini splitlines()menangani baris baru universal sementara split('\n')tidak.
Bakuriu
7
Dan selalu ada os.linesep:)
askewchan
1
@ LarsH, itu akan membantu dalam beberapa keadaan, pada \r\nakhir baris sistem saya tidak dikonversi \n, apakah dibaca sebagai teks atau biner, jadi os.linesepakan bekerja di tempat yang \ntidak. Tapi splitlinesjelas pilihan yang lebih baik, jika Anda menyebutkan di mana file tidak cocok dengan os. Sungguh saya sebagian besar menyebutkannya kalau-kalau orang yang melihat diskusi ini tidak menyadari keberadaannya.
askewchan
1
@askewchan Mungkin Anda menggunakan versi Python yang kedaluwarsa. Saya percaya bahwa pada Python 3, baris universal universal diaktifkan secara default yaitu \r\nakan dikonversi untuk file teks bahkan ketika Anda berjalan di Linux.
Arthur Tacca
13

contoh lain:

Membaca file satu baris pada saat itu. Menghapus karakter yang tidak diinginkan dengan dari ujung stringstr.rstrip(chars)

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

lihat juga str.strip([chars])danstr.lstrip([chars])

(python> = 2.0)

O-9
sumber
10
temp = open(filename,'r').read().splitlines()
Marcel
sumber
5
Apakah Anda yakin ini akan menutup file? Saya pikir tidak, jadi itu bukan benar-benar satu-liner ...
Ray Hulha
9

Saya pikir ini adalah pilihan terbaik.

temp = [line.strip() for line in file.readlines()]
RENZO
sumber
8
Solusi ini juga menghilangkan ruang depan dan belakang, yang tidak dimaksudkan.
Roland Illig
Pemahamannya benar-benar bagus. Setidaknya dengan Python 3, seseorang dapat menggunakan temp = [line.rstrip() for line in file.readlines()]untuk mendapatkan apa yang dimaksudkan oleh @Roland_Illig notes.
bballdave025
Jika Anda akan beralih ke semua baris, mengapa tidak malas? Dengan .readlines(), Anda secara efektif mengulangi seluruh file dua kali.
AMC
1

Coba ini:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  
Nitesh Soni
sumber
4
Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda. Cobalah juga untuk tidak membuat kerumunan kode Anda dengan komentar yang jelas, karena ini mengurangi keterbacaan kode dan penjelasannya!
Selamat tinggal StackExchange
Saya tidak melihat mengapa orang harus menggunakan ini di atas beberapa solusi alternatif.
AMC
-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
sumber
3
Harap tambahkan beberapa penjelasan sehingga akan bermanfaat bagi orang lain.
samuellawrentz
Anda harus menggunakan manajer konteks untuk menangani objek file, dan beralih ke file secara langsung. Dengan menggunakan .readlines()seperti ini, Anda secara efektif mengulangi seluruh file dua kali.
AMC
-2
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])
srus
sumber
2
Tetapi bagaimana jika garis memiliki koma di dalamnya?
gilch
-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;
pengguna4730171
sumber