Làm thế nào để đọc một tập tin mà không có dòng mới?


374

Trong Python, gọi

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

dẫn đến một danh sách trong đó mỗi phần tử là một dòng trong tệp. Đó là một chút ngu ngốc nhưng vẫn: readlines()viết nhân vật dòng mới cho từng yếu tố, điều tôi không muốn xảy ra.

Làm thế nào tôi có thể tránh nó?


4
Sử dụng dải : [l.strip('\n\r') for l in temp]. Hoặc thậm chí rstrip. Và kể từ khi lặp ở đây, nó có thể được in openthay thế in temp.
gorlum0

11
Tôi sẽ rất tuyệt nếu trong Python 3 có một giá trị để đặt newlineđối số của open thành các dòng mới được theo dõi.
jxramos

Câu trả lời:


554

Bạn có thể đọc toàn bộ tập tin và chia dòng bằng cách sử dụng str.splitlines:

temp = file.read().splitlines()

Hoặc bạn có thể tước dòng mới bằng tay:

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

Lưu ý: giải pháp cuối cùng này chỉ hoạt động nếu tệp kết thúc bằng một dòng mới, nếu không dòng cuối cùng sẽ mất một ký tự.

Giả định này là đúng trong hầu hết các trường hợp (đặc biệt đối với các tệp được tạo bởi trình soạn thảo văn bản, thường làm thêm một newline kết thúc anyway).

Nếu bạn muốn tránh điều này, bạn có thể thêm một dòng mới vào cuối tập tin:

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]

Hoặc thay thế đơn giản hơn là stripthay vào dòng mới:

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

Hoặc thậm chí, mặc dù khá khó đọc:

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

Việc khai thác thực tế là giá trị trả về của orkhông phải là boolean, mà là đối tượng được đánh giá đúng hay sai.


Các readlinesphương pháp thực sự là tương đương với:

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

Kể từ khi readline()giữ dòng mới cũng readlines()giữ nó.

Lưu ý: đối với đối xứng để readlines()các writelines()phương pháp nào không thêm kết thúc dòng mới, do đó f2.writelines(f.readlines())tạo ra một bản sao chính xác của ftrong f2.


1
Lưu ý rằng [line.rstrip('\n') for line in file]sẽ loại bỏ nhiều hơn một dấu \n.
Wes Turner

1
Đơn giản hơn, [line[:-(line[-1] == '\n') or len(line)+1] for line in file]thay vào đó có thể được [line[:-(line[-1] == '\n') or None] for line in file].
Wes Turner

10
Các giải pháp này đọc toàn bộ tập tin vào bộ nhớ. Thay đổi dấu ngoặc vuông của việc hiểu danh sách thành dấu ngoặc đơn tạo thành biểu thức trình tạo cho phép bạn lặp lại từng dòng một tệp: for line in (x.strip() for x in f):
Joseph Sheedy

2
@velotron Đó không thực sự là điểm của câu hỏi / câu trả lời. Ngoài ra: hãy nhớ rằng withđóng các tệp khi khối kết thúc, điều đó có nghĩa là bạn không thể thực hiện with open(...) as f: lines = (line for line in f)và sử dụng linesbên ngoài withvì bạn sẽ gặp lỗi I / O. Bạn có thể lười sử dụng một bộ khai thác gen, nhưng bạn phải sử dụng nó trước khi đóng tệp.
Bakuriu

@WesTurner. Nhưng sẽ không có nhiều hơn một dòng mới. Dòng mới bổ sung sẽ là một phần của dòng trống tiếp theo
Mad Physicist

38
temp = open(filename,'r').read().split('\n')

14
Điều gì sẽ xảy ra với \r\ndòng mới mặc dù? ;)
Wolph

26
Python tự động xử lý các dòng mới phổ quát, do đó .split('\n')sẽ phân chia chính xác, độc lập với quy ước dòng mới. Sẽ rất có vấn đề nếu bạn đọc tệp ở chế độ nhị phân. Trong trường hợp đó splitlines()xử lý các dòng mới phổ quát trong khi split('\n')không.
Bakuriu

7
Và luôn luôn có os.linesep:)
askewchan

1
@LarsH, nó sẽ giúp ích trong một số trường hợp, trên các \r\nkết thúc dòng hệ thống của tôi không được chuyển đổi thành \n, dù là đọc dưới dạng văn bản hay nhị phân, vì vậy os.linesepsẽ hoạt động ở nơi \nkhông. Nhưng splitlinesrõ ràng là sự lựa chọn tốt hơn, trong trường hợp bạn đề cập đến nơi tệp không khớp với os. Thực sự tôi chủ yếu đề cập đến nó trong trường hợp mọi người nhìn vào cuộc thảo luận này không biết đến sự tồn tại của nó.
askewchan

1
@askewchan Có lẽ bạn đang sử dụng phiên bản Python đã lỗi thời. Tôi tin rằng kể từ Python 3, các dòng mới phổ biến được bật theo mặc định tức là \r\nsẽ được chuyển đổi cho các tệp văn bản ngay cả khi bạn đang chạy trên Linux.
Arthur Tacca

13

một vi dụ khac:

Đọc tập tin một hàng tại thời điểm đó. Loại bỏ các ký tự không mong muốn với từ cuối chuỗistr.rstrip(chars)

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

xem thêm str.strip([chars])str.lstrip([chars])

(trăn> = 2.0)


10
temp = open(filename,'r').read().splitlines()

5
Bạn có chắc chắn điều này đóng tập tin? Tôi nghĩ là không, vì vậy nó không thực sự là một lớp lót ...
Ray Hulha

9

Tôi nghĩ rằng đây là lựa chọn tốt nhất.

temp = [line.strip() for line in file.readlines()]

8
Giải pháp này cũng loại bỏ các không gian hàng đầu và dấu, không có ý định.
Roland Illig

Sự hiểu biết là thực sự tốt đẹp, mặc dù. Ít nhất là với Python 3, người ta có thể sử dụng temp = [line.rstrip() for line in file.readlines()]để có được những gì ghi chú @Roland_Illig dự định.
bballdave025

Nếu bạn định lặp đi lặp lại tất cả các dòng, tại sao không quá lười biếng? Với .readlines(), bạn đang lặp lại hiệu quả trên toàn bộ tệp hai lần.
AMC

1

Thử cái này:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  

4
Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. Xin vui lòng cố gắng không làm đông mã của bạn với các bình luận giải thích, vì điều này làm giảm khả năng đọc của cả mã và các giải thích!
Tạm biệt StackExchange

Tôi không thấy lý do tại sao mọi người nên sử dụng điều này trên một số giải pháp thay thế.
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() 

3
Vui lòng thêm một số giải thích để nó sẽ hữu ích cho những người khác.
samuellawrentz

Bạn nên sử dụng trình quản lý bối cảnh để xử lý đối tượng tệp và lặp lại trực tiếp tệp. Bằng cách sử dụng .readlines()như thế này, bạn sẽ lặp lại hiệu quả trên toàn bộ tệp hai lần.
AMC

-2
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])

2
Nhưng nếu dòng có dấu phẩy thì sao?
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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.