วิธีที่ดีที่สุดในการอ่านไฟล์ที่คั่นด้วยการขึ้นบรรทัดใหม่และทิ้งขึ้นบรรทัดใหม่?


84

ฉันกำลังพยายามหาวิธีที่ดีที่สุดในการจัดการการลบบรรทัดใหม่เมื่ออ่านไฟล์ที่คั่นด้วยการขึ้นบรรทัดใหม่ใน Python

สิ่งที่ฉันคิดขึ้นคือรหัสต่อไปนี้รวมถึงรหัสการทิ้งเพื่อทดสอบ

import os

def getfile(filename,results):
   f = open(filename)
   filecontents = f.readlines()
   for line in filecontents:
     foo = line.strip('\n')
     results.append(foo)
   return results

blahblah = []

getfile('/tmp/foo',blahblah)

for x in blahblah:
    print x

ข้อเสนอแนะ?


แล้วการใช้ split ("/ n") ล่ะ
jle

1
เหมือนกับ: stackoverflow.com/questions/339537/…
Vijay Dev

ฉันคิดว่ามันจะดีกว่าถ้าปิดไฟล์เช่นกัน
PawełPrażak

คำตอบ:


196
lines = open(filename).read().splitlines()

1
คำตอบนี้ทำในสิ่งที่ฉันต้องการฉันแน่ใจว่าฉันจะต้องเพิ่มการตรวจสอบข้อผิดพลาดและสิ่งนั้น แต่สำหรับความต้องการเฉพาะนี้มันยอดเยี่ยมมาก ขอบคุณทุกท่านที่ให้คำตอบ!
solarce

ฉันชอบสิ่งนี้ แต่คุณจะปิดไฟล์ได้อย่างไรถ้าคุณไม่บันทึกจากที่จับไฟล์ หรือปิดเองโดยอัตโนมัติ?
IJ Kennedy

6
เมื่อใช้ CPython จำนวนอ้างอิงสำหรับอ็อบเจ็กต์ไฟล์จะเป็นศูนย์เมื่อไม่มีการใช้งานอีกต่อไปและไฟล์จะถูกปิดโดยอัตโนมัติ สำหรับการใช้งาน GC อย่างหมดจดเช่น Jython และ IronPython ไฟล์อาจไม่ถูกปิดจนกว่า GC จะทำงาน - ดังนั้นรูปแบบเล็กน้อยนี้อาจไม่เหมาะสม
Curt Hagenlocher

2
บน Mac OS X 10.7.5 พร้อม RAM 8GB ฉันสามารถอ่านไฟล์ได้ถึง 2047MB (นิยามของฉัน: 1 MB = 1024 x 1024 ไบต์) 2048MB จะทำให้เกิดข้อยกเว้น MemoryError
Hai Vu

1
@WKPlus คำถามยอดเยี่ยม - คำตอบคือ "ขึ้นอยู่กับ" stackoverflow.com/a/15099341/994153 (CPython จะปิดเนื่องจากจำนวนอ้างอิงลดลงเหลือศูนย์ แต่การใช้งาน Python อื่น ๆ อาจไม่ปิดดังนั้นจึงควรทำให้ชัดเจนที่สุด )
Colin D Bennett

23

นี่คือเครื่องกำเนิดไฟฟ้าที่ทำตามที่คุณร้องขอ ในกรณีนี้การใช้ rstrip จะเพียงพอและเร็วกว่า strip เล็กน้อย

lines = (line.rstrip('\n') for line in open(filename))

อย่างไรก็ตามคุณมักจะต้องการใช้สิ่งนี้เพื่อกำจัดช่องว่างต่อท้ายด้วย

lines = (line.rstrip() for line in open(filename))

มันไม่ควร [] รอบ RHS ไม่ใช่ ()?
andrewb

8
@andrewb การใช้ () ให้นิพจน์ตัวสร้างซึ่งไม่ใช้หน่วยความจำมากเท่ากับการใช้ [] (ความเข้าใจในรายการ)
Jonathan Hartley

9

คุณคิดอย่างไรเกี่ยวกับแนวทางนี้?

with open(filename) as data:
    datalines = (line.rstrip('\r\n') for line in data)
    for line in datalines:
        ...do something awesome...

นิพจน์ Generator หลีกเลี่ยงการโหลดไฟล์ทั้งหมดลงในหน่วยความจำและwithทำให้แน่ใจว่าปิดไฟล์


นี่เป็นหลักเหมือนกับคำตอบของ @ TimoLinna ที่โพสต์ไว้เมื่อหลายปีก่อน ...
martineau


4

เพียงใช้นิพจน์ตัวสร้าง:

blahblah = (l.rstrip() for l in open(filename))
for x in blahblah:
    print x

นอกจากนี้ฉันต้องการแนะนำให้คุณไม่ต้องอ่านทั้งไฟล์ในหน่วยความจำ - การวนซ้ำบนเครื่องกำเนิดไฟฟ้านั้นมีประสิทธิภาพมากกว่าในชุดข้อมูลขนาดใหญ่


3

ฉันใช้สิ่งนี้

def cleaned( aFile ):
    for line in aFile:
        yield line.strip()

จากนั้นฉันจะทำสิ่งนี้ได้

lines = list( cleaned( open("file","r") ) )

หรือฉันสามารถขยายการทำความสะอาดด้วยฟังก์ชันพิเศษเช่นวางบรรทัดว่างหรือข้ามบรรทัดความคิดเห็นหรืออะไรก็ได้


2

ฉันจะทำเช่นนี้:

f = open('test.txt')
l = [l for l in f.readlines() if l.strip()]
f.close()
print l

แม้ว่าคำตอบของ Curt Hagenlocher จะดีกว่าในทางเทคนิค แต่คำตอบนี้เป็นจุดเริ่มต้นที่ดีหากคุณต้องการเพิ่มการประมวลผลอื่น ๆ ในแต่ละบรรทัด
TomOnTime

ไม่แน่ใจว่ามีจุดประสงค์เพื่อกรองบรรทัดว่างหรือไม่ แต่จะกระชับกว่า... if l.strip() is not ''ซึ่งเป็นสิ่งที่ฉันต้องการในกรณีของฉัน
Zach Young
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.