วิธีอ่านไฟล์ทีละบรรทัดในรายการ


2027

ฉันจะอ่านไฟล์ทุกบรรทัดใน Python และเก็บแต่ละบรรทัดเป็นองค์ประกอบในรายการได้อย่างไร

ฉันต้องการอ่านไฟล์ทีละบรรทัดและต่อท้ายแต่ละบรรทัดต่อท้ายรายการ

คำตอบ:


2174
with open(filename) as f:
    content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content] 

206
อย่าใช้file.readlines()ในfor-loop วัตถุไฟล์นั้นก็เพียงพอแล้ว:lines = [line.rstrip('\n') for line in file]
jfs

88
ในกรณีที่คุณกำลังทำงานกับข้อมูลขนาดใหญ่ใช้readlines()ไม่ได้มีประสิทธิภาพมากอย่างที่มันสามารถส่งผลในMemoryError ในกรณีนี้จะเป็นการดีกว่าที่จะวนซ้ำไฟล์ที่ใช้for line in f:และทำงานกับlineตัวแปรแต่ละตัว
DarkCygnus

7
ฉันจะตรวจสอบรายละเอียดความทรงจำของวิธีการต่าง ๆ ที่กำหนดในคำตอบโดยใช้ขั้นตอนที่กล่าวถึงที่นี่ ใช้หน่วยความจำจะดีเมื่อแต่ละบรรทัดจะถูกอ่านจากไฟล์และการประมวลผลตามที่แนะนำโดย @DevShark ที่นี่ การถือทุกบรรทัดในวัตถุรวบรวมไม่ใช่ความคิดที่ดีถ้าหน่วยความจำมีข้อ จำกัด หรือไฟล์มีขนาดใหญ่ เวลาดำเนินการจะคล้ายกันในทั้งสองแนวทาง
Tirtha R

6
นอกจากนี้.rstrip()จะทำงานได้เร็วขึ้นเล็กน้อยหากคุณเปิดช่องว่างจากปลายเส้น
Gringo Suave

Oneliner:with open(filename) as f: content = [i.strip() for i in f.readlines()]
Vishal Gupta

1002

ดูอินพุตและ Ouput :

with open('filename') as f:
    lines = f.readlines()

หรือลอกอักขระขึ้นบรรทัดใหม่:

with open('filename') as f:
    lines = [line.rstrip() for line in f]

12
ดีกว่าใช้f.read().splitlines()ซึ่งจะลบบรรทัดใหม่
ทำเครื่องหมาย

รุ่นที่สองfor line in open(filename)ปลอดภัยไหม นั่นคือไฟล์จะถูกปิดโดยอัตโนมัติหรือไม่
becko

2
ดีที่สุดในการอ่านไฟล์ครั้งละหนึ่งบรรทัดแทนที่จะอ่านไฟล์ทั้งหมดในหน่วยความจำทั้งหมดในครั้งเดียว การทำเช่นนี้จะไม่ขยายขนาดได้ดีกับไฟล์อินพุตขนาดใหญ่ ดูคำตอบด้านล่างโดย robert
แบรดไฮน์

1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]ถ้าฉันเขียนด้วยวิธีนี้ฉันจะปิดไฟล์หลังจากอ่านได้อย่างไร
Ramisa Anjum Aditi

2
ใช่จนถึงจุดที่คนอื่นกำลังทำที่นี่ในขณะที่มันไม่ใช่ "แนวปฏิบัติที่ดีที่สุด" ที่จะใช้openโดยไม่มีตัวจัดการบริบท (หรือวิธีอื่นที่รับประกันได้ว่าจะปิด) สิ่งนี้ไม่ใช่กรณีเหล่านี้จริง ๆ - เมื่อวัตถุไม่มีการอ้างอิงเพิ่มเติม ไปมันจะถูกเก็บรวบรวมขยะและไฟล์ที่ปิดซึ่งควรจะเกิดขึ้นทันทีในข้อผิดพลาดหรือไม่เมื่อรายการความเข้าใจจะเสร็จสิ้นการประมวลผล
Aaron Hall

579

ชัดเจนกว่าที่จำเป็น แต่ทำในสิ่งที่คุณต้องการ

with open("file.txt") as file_in:
    lines = []
    for line in file_in:
        lines.append(line)

18
ฉันชอบคำตอบนี้เพราะไม่จำเป็นต้องโหลดไฟล์ทั้งหมดในหน่วยความจำ (ในกรณีนี้มันยังผนวกเข้ากับarrayแต่อาจมีสถานการณ์อื่น) แน่นอนว่าสำหรับไฟล์ขนาดใหญ่วิธีนี้อาจช่วยลดปัญหาได้
JohannesB

1
การต่อท้ายอาร์เรย์จะช้า ฉันไม่สามารถนึกถึงกรณีการใช้งานที่นี่เป็นทางออกที่ดีที่สุด
Elias Strehle

@haccks มันจะดีกว่าเพราะมันไม่ได้โหลดไฟล์ทั้งหมดไปยังหน่วยความจำหรือมีมากกว่านั้น?
OrigamiEye

4
หมายเหตุ:วิธีนี้ไม่ได้ตัดบรรทัดใหม่
AMC

1
วิธีนี้จะโหลดไฟล์ทั้งหมดลงในหน่วยความจำ ฉันไม่รู้ว่าทำไมคนถึงคิดว่ามันไม่
andrebrait

274

สิ่งนี้จะให้ผลเป็น "อาร์เรย์" ของบรรทัดจากไฟล์

lines = tuple(open(filename, 'r'))

openส่งคืนไฟล์ที่สามารถวนซ้ำได้ เมื่อคุณวนซ้ำไฟล์คุณจะได้รับบรรทัดจากไฟล์นั้น tupleสามารถใช้ตัววนซ้ำและยกตัวอย่างอินสแตนซ์ tuple ให้คุณจากตัววนซ้ำที่คุณให้ linesคือ tuple ที่สร้างจากบรรทัดของไฟล์


31
@MarshallFarrier ลองlines = open(filename).read().split('\n')แทน
Noctis Skytower

16
มันปิดไฟล์หรือไม่
Vanuan

5
@Vanuan เนื่องจากไม่มีการอ้างอิงที่เหลืออยู่กับไฟล์หลังจากรันบรรทัดแล้ว destructor ควรปิดไฟล์โดยอัตโนมัติ
Noctis Skytower

30
@NocctisSkytower ฉันพบว่าlines = open(filename).read().splitlines()สะอาดขึ้นเล็กน้อยและฉันเชื่อว่ามันยังจัดการกับจุดสิ้นสุดของ DOS ได้ดีกว่า
jaynp

8
@ mklement0 สมมติไฟล์ 1000 สายเป็นlistเวลาถึงเกี่ยวกับพื้นที่ 13.22% tupleมากขึ้นกว่า from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2)ผลมาจาก การสร้างtupleใช้เวลานานกว่าการสร้างประมาณ 4.17% list(ด้วยส่วนเบี่ยงเบนมาตรฐาน 0.16%) ผลลัพธ์มาจากการรันfrom timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)30 ครั้ง โซลูชันของฉันโปรดปรานพื้นที่มากกว่าความเร็วเมื่อไม่ทราบความต้องการความไม่แน่นอน
Noctis Skytower

194

ถ้าคุณต้องการ\nรวม:

with open(fname) as f:
    content = f.readlines()

หากคุณไม่ต้องการ\nรวม:

with open(fname) as f:
    content = f.read().splitlines()

168

ตามวิธีการของ Python ของ File Objectsวิธีที่ง่ายที่สุดในการแปลงไฟล์ข้อความเป็น a listคือ:

with open('file.txt') as f:
    my_list = list(f)

หากคุณต้องการทำซ้ำบรรทัดไฟล์ข้อความคุณสามารถใช้:

with open('file.txt') as f:
    for line in f:
       ...

คำตอบเก่า:

การใช้withและreadlines():

with open('file.txt') as f:
    lines = f.readlines()

หากคุณไม่สนใจเกี่ยวกับการปิดไฟล์หนึ่งบรรทัดนี้ใช้งานได้:

lines = open('file.txt').readlines()

ดั้งเดิมวิธี:

f = open('file.txt') # Open file on read mode
lines = f.read().split("\n") # Create a list containing all lines
f.close() # Close file

150

คุณสามารถทำสิ่งต่อไปนี้ตามที่ได้รับการแนะนำ:

with open('/your/path/file') as f:
    my_lines = f.readlines()

โปรดทราบว่าวิธีนี้มีข้อเสีย 2 ข้อ:

1) คุณเก็บทุกบรรทัดในหน่วยความจำ ในกรณีทั่วไปนี่เป็นความคิดที่แย่มาก ไฟล์อาจมีขนาดใหญ่มากและคุณอาจมีหน่วยความจำไม่เพียงพอ แม้ว่ามันจะไม่ใหญ่ แต่มันก็เป็นความทรงจำที่เสียเปล่า

2) สิ่งนี้ไม่อนุญาตให้ประมวลผลแต่ละบรรทัดเมื่อคุณอ่าน ดังนั้นหากคุณประมวลผลรายการของคุณหลังจากนี้จะไม่มีประสิทธิภาพ (ต้องผ่านสองครั้งมากกว่าหนึ่งรายการ)

แนวทางที่ดีกว่าสำหรับกรณีทั่วไปคือ:

with open('/your/path/file') as f:
    for line in f:
        process(line)

ที่ซึ่งคุณกำหนดฟังก์ชั่นกระบวนการในแบบที่คุณต้องการ ตัวอย่างเช่น:

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

(การดำเนินการในSupermanชั้นเรียนจะถูกทิ้งไว้เป็นแบบฝึกหัดสำหรับคุณ)

มันจะทำงานได้ดีกับไฟล์ทุกขนาดและคุณต้องผ่านไฟล์ของคุณเพียงแค่ 1 pass นี่คือวิธีการแยกวิเคราะห์ทั่วไปที่จะทำงาน


5
นี่คือสิ่งที่ฉันต้องการ - และขอบคุณสำหรับการอธิบายข้อเสีย ในฐานะผู้เริ่มต้นใน Python มันยอดเยี่ยมมากที่ได้เข้าใจว่าทำไมการแก้ปัญหาจึงเป็นวิธีแก้ปัญหา ไชโย!
Ephexx

5
คิดว่า Corey อีกเล็กน้อย คุณต้องการให้คอมพิวเตอร์ของคุณอ่านแต่ละบรรทัดโดยไม่ทำอะไรกับบรรทัดเหล่านี้หรือไม่? แน่นอนคุณสามารถรู้ได้ว่าคุณจำเป็นต้องดำเนินการกับพวกเขาไม่ทางใดก็ทางหนึ่ง
DevShark

5
คุณต้องทำอะไรกับเส้นเสมอ สามารถทำได้ง่ายเพียงพิมพ์เส้นหรือนับพวกเขา ไม่มีค่าในการทำให้กระบวนการของคุณอ่านบรรทัดในหน่วยความจำ แต่ไม่ทำอะไรกับมัน
DevShark

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

2
@PierreOcinom ที่ถูกต้อง เนื่องจากไฟล์ถูกเปิดในโหมดอ่านอย่างเดียวคุณจะไม่สามารถแก้ไขไฟล์ต้นฉบับด้วยรหัสด้านบน หากต้องการเปิดไฟล์สำหรับทั้งการอ่านและการเขียนให้ใช้open('file_path', 'r+')
DevShark

64

ข้อมูลลงในรายการ

สมมติว่าเรามีไฟล์ข้อความที่มีข้อมูลเหมือนในบรรทัดต่อไปนี้

เนื้อหาไฟล์ข้อความ:

line 1
line 2
line 3
  • เปิด cmd ในไดเรกทอรีเดียวกัน (คลิกขวาที่เมาส์แล้วเลือก cmd หรือ PowerShell)
  • เรียกใช้pythonและในล่ามเขียน:

สคริปต์ Python:

>>> with open("myfile.txt", encoding="utf-8") as file:
...     x = [l.strip() for l in file]
>>> x
['line 1','line 2','line 3']

ใช้ผนวก:

x = []
with open("myfile.txt") as file:
    for l in file:
        x.append(l.strip())

หรือ:

>>> x = open("myfile.txt").read().splitlines()
>>> x
['line 1', 'line 2', 'line 3']

หรือ:

>>> x = open("myfile.txt").readlines()
>>> x
['linea 1\n', 'line 2\n', 'line 3\n']

หรือ:

def print_output(lines_in_textfile):
    print("lines_in_textfile =", lines_in_textfile)

y = [x.rstrip() for x in open("001.txt")]
print_output(y)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = file.read().splitlines()
    print_output(file)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = [x.strip() for x in file.readlines()]
    print_output(file)

เอาท์พุท:

lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']

เป็นencoding="utf-8"ต้อง?
Mausy5043

@ Mausy5043 ไม่ แต่เมื่อคุณอ่านไฟล์ข้อความคุณสามารถมีตัวละครแปลก ๆ (เป็นภาษาอิตาลีโดยเฉพาะ)
Giovanni G. PY

1
read().splitlines()Python ให้บริการแก่คุณ: เป็นเพียงreadlines()(ซึ่งอาจเร็วกว่าเนื่องจากมีความสิ้นเปลืองน้อยกว่า)
Eric O Lebigot

@EricOLebigot จากตัวอย่างที่แสดงดูเหมือนread().splitlines()และreadlines()ไม่สร้างผลลัพธ์เดียวกัน คุณแน่ใจหรือว่าพวกเขาเทียบเท่า
craq

หากคุณใช้ readlines เท่านั้นคุณต้องใช้วิธี strip เพื่อกำจัด \ n ในข้อความดังนั้นฉันเปลี่ยนตัวอย่างสุดท้ายโดยใช้ list comprehension เพื่อให้ได้ผลลัพธ์เดียวกันในทั้งสองกรณี ดังนั้นหากคุณใช้ read () readlines () คุณจะมีรายการ "clean" ที่มีบรรทัดและไม่มีอักขระขึ้นบรรทัดใหม่มิฉะนั้นคุณต้องทำสิ่งที่คุณเห็นในโค้ดด้านบน
Giovanni G. PY

43

หากต้องการอ่านไฟล์ลงในรายการคุณต้องทำสามสิ่ง:

  • เปิดไฟล์
  • อ่านไฟล์
  • เก็บเนื้อหาเป็นรายการ

โชคดีที่ Python ทำให้การทำสิ่งเหล่านี้ง่ายมากดังนั้นวิธีที่สั้นที่สุดในการอ่านไฟล์ลงในรายการคือ:

lst = list(open(filename))

อย่างไรก็ตามฉันจะเพิ่มคำอธิบายเพิ่มเติม

กำลังเปิดไฟล์

ฉันคิดว่าคุณต้องการเปิดไฟล์ที่เฉพาะเจาะจงและคุณไม่ได้จัดการโดยตรงกับการจัดการไฟล์ (หรือการจัดการไฟล์) ฟังก์ชั่นที่ใช้บ่อยที่สุดในการเปิดไฟล์ใน Python คือopenมันต้องใช้อาร์กิวเมนต์หนึ่งตัวและอีกสองตัวเลือกใน Python 2.7:

  • ชื่อไฟล์
  • โหมด
  • การบัฟเฟอร์ (ฉันจะไม่สนใจอาร์กิวเมนต์นี้ในคำตอบนี้)

ชื่อไฟล์ที่ควรจะเป็นสตริงที่แสดงเป็นเส้นทางไปยังแฟ้ม ตัวอย่างเช่น:

open('afile')   # opens the file named afile in the current working directory
open('adir/afile')            # relative path (relative to the current working directory)
open('C:/users/aname/afile')  # absolute path (windows)
open('/usr/local/afile')      # absolute path (linux)

โปรดทราบว่าจำเป็นต้องระบุนามสกุลไฟล์ สิ่งนี้มีความสำคัญอย่างยิ่งสำหรับผู้ใช้ Windows เนื่องจากนามสกุลไฟล์เช่น.txtหรือ.docอื่น ๆ จะถูกซ่อนไว้ตามค่าเริ่มต้นเมื่อดูใน explorer

อาร์กิวเมนต์ที่สองคือmodeมันเป็นrไปโดยปริยายซึ่งหมายความว่า "อ่านอย่างเดียว" นั่นคือสิ่งที่คุณต้องการในกรณีของคุณ

แต่ในกรณีที่คุณต้องการสร้างไฟล์และ / หรือเขียนลงไฟล์คุณจะต้องมีอาร์กิวเมนต์ที่แตกต่างกันที่นี่ มีคำตอบที่ดีคือถ้าคุณต้องการภาพรวม

สำหรับการอ่านไฟล์คุณสามารถละเว้นmodeหรือส่งมันอย่างชัดเจน:

open(filename)
open(filename, 'r')

ทั้งสองจะเปิดไฟล์ในโหมดอ่านอย่างเดียว ในกรณีที่คุณต้องการอ่านในไฟล์ไบนารีบน Windows คุณต้องใช้โหมดrb:

open(filename, 'rb')

บนแพลตฟอร์มอื่น ๆ'b'(โหมดไบนารี) จะถูกละเว้นเพียง


ตอนนี้ฉันได้แสดงให้เห็นถึงวิธีการopenของไฟล์มาพูดคุยเกี่ยวกับความจริงที่ว่าคุณต้องการcloseมันอีกครั้ง มิฉะนั้นจะเก็บที่จับเปิดไฟล์ไว้กับไฟล์จนกว่ากระบวนการจะออก (หรือ Python เก็บที่จับไฟล์)

ในขณะที่คุณสามารถใช้:

f = open(filename)
# ... do stuff with f
f.close()

ที่จะล้มเหลวในการปิดไฟล์เมื่อบางสิ่งระหว่างopenและcloseข้อยกเว้น คุณสามารถหลีกเลี่ยงได้โดยใช้tryและfinally:

f = open(filename)
# nothing in between!
try:
    # do stuff with f
finally:
    f.close()

อย่างไรก็ตาม Python จัดให้มีตัวจัดการบริบทที่มีไวยากรณ์ที่ดีกว่า (แต่openมันเกือบจะเหมือนกับtryและfinallyเหนือ):

with open(filename) as f:
    # do stuff with f
# The file is always closed after the with-scope ends.

วิธีสุดท้ายคือวิธีที่แนะนำในการเปิดไฟล์ใน Python!

กำลังอ่านไฟล์

ตกลงคุณได้เปิดไฟล์แล้วจะอ่านอย่างไร

openฟังก์ชันส่งกลับfileวัตถุและรองรับโพรโทคองูเหลือมซ้ำ การทำซ้ำแต่ละครั้งจะทำให้คุณมีบรรทัด:

with open(filename) as f:
    for line in f:
        print(line)

นี่จะพิมพ์แต่ละบรรทัดของไฟล์ โปรดทราบว่าแต่ละบรรทัดจะมีอักขระขึ้นบรรทัดใหม่\nในตอนท้าย (คุณอาจต้องการตรวจสอบว่า Python ของคุณถูกสร้างขึ้นด้วยการสนับสนุนบรรทัดใหม่สากล - ไม่เช่นนั้นคุณอาจมี\r\nWindows หรือ\rMac เป็นบรรทัดใหม่ก็ได้) หากคุณไม่ต้องการให้คุณสามารถลบอักขระสุดท้าย (หรืออักขระสองตัวสุดท้ายบน Windows):

with open(filename) as f:
    for line in f:
        print(line[:-1])

แต่บรรทัดสุดท้ายไม่จำเป็นต้องขึ้นบรรทัดใหม่ดังนั้นจึงไม่ควรใช้ หนึ่งสามารถตรวจสอบว่ามันจบลงด้วยการขึ้นบรรทัดใหม่และถ้าเป็นเช่นนั้นลบ:

with open(filename) as f:
    for line in f:
        if line.endswith('\n'):
            line = line[:-1]
        print(line)

แต่คุณสามารถลบ whitespaces ทั้งหมด (รวมถึง\nตัวละคร) ออกจากส่วนท้ายของสตริงซึ่งจะเป็นการลบwhitespaces ต่อท้ายอื่น ๆ ทั้งหมดดังนั้นคุณต้องระวังหากสิ่งเหล่านี้สำคัญ:

with open(filename) as f:
    for line in f:
        print(f.rstrip())

อย่างไรก็ตามหากบรรทัดลงท้ายด้วย\r\n(Windows "newlines") ที่.rstrip()จะดูแล\r!

เก็บเนื้อหาเป็นรายการ

ตอนนี้คุณรู้วิธีเปิดไฟล์และอ่านแล้วได้เวลาเก็บเนื้อหาในรายการ ตัวเลือกที่ง่ายที่สุดคือการใช้listฟังก์ชั่น:

with open(filename) as f:
    lst = list(f)

ในกรณีที่คุณต้องการตัดบรรทัดใหม่ต่อท้ายคุณสามารถใช้ list comprehension แทน:

with open(filename) as f:
    lst = [line.rstrip() for line in f]

หรือง่ายยิ่งขึ้น: .readlines()เมธอดของfileอ๊อบเจคโดยปริยายจะคืนค่า a listของบรรทัด:

with open(filename) as f:
    lst = f.readlines()

ซึ่งจะรวมถึงอักขระบรรทัดใหม่ต่อท้ายหากคุณไม่ต้องการให้ฉันแนะนำ[line.rstrip() for line in f]วิธีการนี้เนื่องจากจะหลีกเลี่ยงการเก็บสองรายการที่มีบรรทัดทั้งหมดในหน่วยความจำ

มีตัวเลือกเพิ่มเติมเพื่อให้ได้ผลลัพธ์ที่ต้องการอย่างไรก็ตามมันค่อนข้าง "suboptimal": readไฟล์ที่สมบูรณ์ในสตริงแล้วแบ่งเป็นบรรทัดใหม่:

with open(filename) as f:
    lst = f.read().split('\n')

หรือ:

with open(filename) as f:
    lst = f.read().splitlines()

สิ่งเหล่านี้จะขึ้นบรรทัดใหม่ต่อท้ายโดยอัตโนมัติเนื่องจากไม่มีsplitอักขระอยู่ อย่างไรก็ตามมันไม่เหมาะเพราะคุณเก็บไฟล์เป็นสตริงและเป็นรายการของเส้นในหน่วยความจำ!

สรุป

  • ใช้with open(...) as fเมื่อเปิดไฟล์เพราะคุณไม่จำเป็นต้องปิดไฟล์เองและจะปิดไฟล์แม้ว่าจะมีข้อยกเว้นเกิดขึ้น
  • filefor line in the_file_object:วัตถุสนับสนุนโปรโตคอลซ้ำเพื่ออ่านไฟล์บรรทัดโดยบรรทัดเป็นง่ายๆเป็น
  • เรียกดูเอกสารประกอบสำหรับฟังก์ชั่น / ชั้นเรียนที่มีอยู่เสมอ เวลาส่วนใหญ่มีการจับคู่ที่สมบูรณ์แบบสำหรับงานหรืออย่างน้อยหนึ่งหรือสองคนที่ดี ตัวเลือกที่ชัดเจนในกรณีนี้จะเป็นreadlines()แต่ถ้าคุณต้องการประมวลผลบรรทัดก่อนที่จะเก็บไว้ในรายการฉันจะแนะนำรายการเข้าใจง่าย

วิธีสุดท้ายคือวิธีที่แนะนำในการเปิดไฟล์ใน Python! ทำไมจึงเป็นเช่นนั้น คนส่วนใหญ่จะไม่เพียง แต่มองในสองสามบรรทัดแรกของคำตอบก่อนที่จะไป?
AMC

@AMC ฉันไม่ได้คิดมากเมื่อเขียนคำตอบ คุณคิดว่าฉันควรวางไว้ที่ด้านบนของคำตอบหรือไม่
MSeifert

มันอาจจะดีที่สุดใช่ ฉันเพิ่งสังเกตเห็นว่าคุณพูดถึง Python 2 เพื่อให้สามารถอัปเดตได้เช่นกัน
AMC

คำถามเดิมติดแท็ก python-2.x แล้ว อาจทำให้รู้สึกถึงการอัพเดทโดยทั่วไป ฉันจะดูว่าฉันจะมาที่ในครั้งต่อไป ขอบคุณสำหรับคำแนะนำของคุณ ชื่นชมมาก!
MSeifert

42

วิธีที่สะอาดและเป็นระบบในการอ่านบรรทัดของไฟล์ไปสู่รายการ


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

infile = open('my_file.txt', 'r')  # Open the file for reading.

data = infile.read()  # Read the contents of the file.

infile.close()  # Close the file since we're done using it.

แต่ฉันชอบวิธีการด้านล่างของการเปิดไฟล์สำหรับทั้งการอ่านและการเขียนเนื่องจากมันสะอาดมากและไม่จำเป็นต้องมีขั้นตอนพิเศษในการปิดไฟล์เมื่อคุณใช้เสร็จแล้ว ในคำสั่งด้านล่างเรากำลังเปิดไฟล์สำหรับอ่านและกำหนดให้กับตัวแปร 'infile' เมื่อรหัสในคำสั่งนี้ทำงานเสร็จไฟล์จะถูกปิดโดยอัตโนมัติ

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

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

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

ผลิตภัณฑ์สุดท้าย:

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

ทดสอบรหัสของเรา:

  • เนื้อหาของไฟล์ข้อความ:
     A fost odatã ca-n povesti,
     A fost ca niciodatã,
     Din rude mãri împãrãtesti,
     O prea frumoasã fatã.
  • พิมพ์คำแถลงเพื่อวัตถุประสงค์ในการทดสอบ:
    print my_list  # Print the list.

    # Print each line in the list.
    for line in my_list:
        print line

    # Print the fourth element in this list.
    print my_list[3]
  • เอาท์พุท (รูปลักษณ์ที่แตกต่างกันเพราะอักขระ Unicode):
     ['A fost odat\xc3\xa3 ca-n povesti,', 'A fost ca niciodat\xc3\xa3,',
     'Din rude m\xc3\xa3ri \xc3\xaemp\xc3\xa3r\xc3\xa3testi,', 'O prea
     frumoas\xc3\xa3 fat\xc3\xa3.']

     A fost odatã ca-n povesti, A fost ca niciodatã, Din rude mãri
     împãrãtesti, O prea frumoasã fatã.

     O prea frumoasã fatã.

30

เปิดตัวใน Python 3.4 pathlibมีวิธีที่สะดวกมากในการอ่านข้อความจากไฟล์ดังนี้:

from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()

(การsplitlinesเรียกเป็นสิ่งที่เปลี่ยนจากสตริงที่มีเนื้อหาทั้งหมดของไฟล์เป็นรายการของบรรทัดในไฟล์)

pathlibมีสิ่งอำนวยความสะดวกมากมายในนั้น read_textเป็นคนดีและรัดกุมและคุณไม่ต้องกังวลเกี่ยวกับการเปิดและปิดไฟล์ หากสิ่งที่คุณต้องทำเกี่ยวกับไฟล์นั้นถูกอ่านทั้งหมดในครั้งเดียวมันเป็นตัวเลือกที่ดี


29

นี่คืออีกหนึ่งตัวเลือกโดยใช้รายการความเข้าใจในไฟล์;

lines = [line.rstrip() for line in open('file.txt')]

นี่ควรเป็นวิธีที่มีประสิทธิภาพมากขึ้นเนื่องจากงานส่วนใหญ่ทำในล่าม Python


10
rstrip()อาจตัดช่องว่างต่อท้ายทั้งหมดไม่เพียง แต่\n; .rstrip('\n')ใช้
mklement0

สิ่งนี้ยังไม่รับประกันว่าไฟล์จะถูกปิดหลังจากอ่านในการใช้งาน Python ทั้งหมด (ใน CPython การใช้ Python หลักจะเป็นเช่นนั้น)
Mark Amery

1
วิธีนี้ควรมีประสิทธิภาพมากขึ้นเนื่องจากงานส่วนใหญ่ทำในล่าม Python นั่นหมายความว่าอย่างไร?
AMC

28
f = open("your_file.txt",'r')
out = f.readlines() # will append in the list out

ตอนนี้ตัวแปรออกเป็นรายการ (อาร์เรย์) ของสิ่งที่คุณต้องการ คุณสามารถทำได้:

for line in out:
    print (line)

หรือ:

for line in f:
    print (line)

คุณจะได้รับผลลัพธ์เดียวกัน


27

อ่านและเขียนไฟล์ข้อความด้วย Python 2 และ Python 3 มันทำงานร่วมกับ Unicode

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Define data
lines = ['     A first string  ',
         'A Unicode sample: €',
         'German: äöüß']

# Write text file
with open('file.txt', 'w') as fp:
    fp.write('\n'.join(lines))

# Read text file
with open('file.txt', 'r') as fp:
    read_lines = fp.readlines()
    read_lines = [line.rstrip('\n') for line in read_lines]

print(lines == read_lines)

สิ่งที่ควรสังเกต:

  • withเป็นสิ่งที่เรียกว่าผู้จัดการบริบท ตรวจสอบให้แน่ใจว่าไฟล์ที่เปิดอยู่ถูกปิดอีกครั้ง
  • โซลูชันทั้งหมดที่นี่สร้าง.strip()หรือ.rstrip()ไม่สามารถทำซ้ำได้linesเนื่องจากยังตัดพื้นที่สีขาว

การสิ้นสุดไฟล์ทั่วไป

.txt

การเขียน / อ่านไฟล์ขั้นสูงเพิ่มเติม

สำหรับแอปพลิเคชันของคุณข้อมูลต่อไปนี้อาจสำคัญ:

  • สนับสนุนโดยภาษาโปรแกรมอื่น ๆ
  • การอ่าน / เขียนประสิทธิภาพ
  • ความกะทัดรัด (ขนาดไฟล์)

ดูเพิ่มเติม: การเปรียบเทียบรูปแบบการจัดลำดับข้อมูล

ในกรณีที่คุณกำลังค่อนข้างมองหาวิธีที่จะทำให้แฟ้มการกำหนดค่าที่คุณอาจต้องการที่จะอ่านบทความสั้น ๆ ของฉันแฟ้มการกำหนดค่าในหลาม


26

ตัวเลือกอื่นคือnumpy.genfromtxtตัวอย่างเช่น:

import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")

สิ่งนี้จะทำให้dataอาร์เรย์ NumPy มีแถวมากเท่ากับที่อยู่ในไฟล์ของคุณ


25

หากคุณต้องการอ่านไฟล์จากบรรทัดคำสั่งหรือจาก stdin คุณสามารถใช้fileinputโมดูล:

# reader.py
import fileinput

content = []
for line in fileinput.input():
    content.append(line.strip())

fileinput.close()

ส่งต่อไฟล์แบบนี้:

$ python reader.py textfile.txt 

อ่านเพิ่มเติมได้ที่นี่: http://docs.python.org/2/library/fileinput.html


20

วิธีที่ง่ายที่สุดที่จะทำ

วิธีง่ายๆคือ:

  1. อ่านไฟล์ทั้งหมดเป็นสตริง
  2. แยกสายสตริงโดยบรรทัด

ในหนึ่งบรรทัดที่จะให้:

lines = open('C:/path/file.txt').read().splitlines()

อย่างไรก็ตามวิธีนี้ค่อนข้างไม่มีประสิทธิภาพเนื่องจากจะเก็บเนื้อหา 2 รุ่นในหน่วยความจำ (อาจไม่ใช่ปัญหาใหญ่สำหรับไฟล์ขนาดเล็ก แต่ยังคงมี) [ขอบคุณ Mark Amery]

มี 2 ​​วิธีง่ายกว่า:

  1. การใช้ไฟล์เป็นตัววนซ้ำ
lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]
  1. หากคุณใช้ Python 3.4 ขึ้นpathlibไปให้ใช้เพื่อสร้างพา ธ สำหรับไฟล์ของคุณที่คุณสามารถใช้สำหรับการทำงานอื่น ๆ ในโปรแกรมของคุณ:
from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]

นี่เป็นวิธีการที่ไม่ดี สำหรับสิ่งหนึ่งที่เรียกร้อง.read().splitlines()ไม่ได้อยู่ในทางใดทางหนึ่ง "ง่าย" .readlines()กว่าเพียงแค่โทร อีกอย่างหนึ่งคือหน่วยความจำไม่มีประสิทธิภาพ คุณไม่จำเป็นต้องจัดเก็บเนื้อหาไฟล์สองเวอร์ชัน (สตริงเดียวที่ส่งคืนโดย.read()และรายการสตริงที่ส่งคืนโดยsplitlines()) ในหน่วยความจำพร้อมกัน
Mark Amery

@MarkAmery True ขอขอบคุณที่เน้นสิ่งนี้ ฉันได้อัพเดตคำตอบแล้ว
Jean-Francois T.

14

เพียงใช้ฟังก์ชั่น splitlines () นี่คือตัวอย่าง

inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3

ในผลลัพธ์คุณจะมีรายการของบรรทัด


.readlines()หน่วยความจำที่ไม่มีประสิทธิภาพเทียบกับการใช้ สิ่งนี้ทำให้สำเนาสองไฟล์ของเนื้อหาในหน่วยความจำพร้อมกัน (หนึ่งเป็นสตริงขนาดใหญ่เดียวหนึ่งเป็นรายการของบรรทัด)
ทำเครื่องหมาย Amery

11

หากคุณต้องการเผชิญหน้ากับไฟล์ที่มีขนาดใหญ่ / ใหญ่และต้องการอ่านเร็วขึ้น (ลองจินตนาการว่าคุณอยู่ในการแข่งขันการเข้ารหัส Topcoder / Hackerrank) คุณอาจอ่านบรรทัดที่มีขนาดใหญ่กว่ามากในบัฟเฟอร์หน่วยความจำในคราวเดียวแทนที่จะเป็น เพียงวนซ้ำทีละบรรทัดที่ระดับไฟล์

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)

กระบวนการ (บรรทัด) ทำอะไร ฉันได้รับข้อผิดพลาดว่าไม่มีการกำหนดตัวแปรดังกล่าว ฉันเดาว่ามีบางสิ่งที่ต้องการนำเข้าและฉันพยายามนำเข้ากระบวนการหลายตัวประมวลผล แต่นั่นไม่ใช่สิ่งที่ฉันเดา คุณช่วยอธิบายรายละเอียดได้ไหม? ขอบคุณ
Newskooler

1
process(line)เป็นฟังก์ชันที่คุณต้องใช้ในการประมวลผลข้อมูล ตัวอย่างเช่นแทนที่จะเป็นบรรทัดนั้นถ้าคุณใช้print(line)มันจะพิมพ์แต่ละบรรทัดจาก lines_buffer
Khanal

f.readlines (buffersize) ส่งคืนบัฟเฟอร์ที่ไม่เปลี่ยนรูป ถ้าคุณต้องการอ่านโดยตรงลงในบัฟเฟอร์ของคุณคุณต้องใช้ readinto () ฟังก์ชั่น ฉันจะเร็วขึ้นมาก
David Dehghan

7

วิธีที่ง่ายที่สุดในการทำเช่นนั้นพร้อมกับสิทธิประโยชน์เพิ่มเติมคือ:

lines = list(open('filename'))

หรือ

lines = tuple(open('filename'))

หรือ

lines = set(open('filename'))

ในกรณีที่มี setเราต้องจำไว้ว่าเราไม่มีคำสั่งซื้อที่สงวนไว้และกำจัดบรรทัดที่ซ้ำกัน

ด้านล่างฉันได้เพิ่มอาหารเสริมที่สำคัญจาก@MarkAmery :

เนื่องจากคุณไม่ได้โทรหา.closeวัตถุไฟล์หรือใช้withคำสั่งในการใช้งานPythonบางไฟล์อาจไม่ได้ปิดหลังจากอ่านและกระบวนการของคุณจะรั่วไหลที่จับเปิดไฟล์ไฟล์อาจไม่ได้รับหลังจากปิดการอ่านและกระบวนการของคุณจะรั่วไหลจับเปิดแฟ้ม

ในCPython (การใช้งานPythonปกติที่คนส่วนใหญ่ใช้) นี่ไม่ใช่ปัญหาเนื่องจากวัตถุไฟล์จะได้รับการรวบรวมขยะทันทีและจะปิดไฟล์ แต่โดยทั่วไปแล้วถือว่าเป็นการปฏิบัติที่ดีที่สุดในการทำสิ่งต่อไปนี้ :

with open('filename') as f: lines = list(f) 

เพื่อให้แน่ใจว่าไฟล์จะถูกปิดไม่ว่าคุณจะใช้Python แบบใด


1
เนื่องจากคุณไม่ได้โทรหา.closeวัตถุไฟล์หรือใช้withคำสั่งในการใช้งาน Python บางไฟล์อาจไม่ได้ปิดหลังจากอ่านและกระบวนการของคุณจะรั่วไหลที่จับเปิดไฟล์ ใน CPython (การใช้งาน Python ปกติที่คนส่วนใหญ่ใช้) นี่ไม่ใช่ปัญหาเนื่องจากวัตถุไฟล์จะได้รับการรวบรวมขยะทันทีและจะปิดไฟล์ แต่โดยทั่วไปถือว่าเป็นการปฏิบัติที่ดีที่สุดwith open('filename') as f: lines = list(f)เพื่อให้แน่ใจว่า ไฟล์ถูกปิดโดยไม่คำนึงถึงการใช้งาน Python ที่คุณใช้
Mark Amery

ขอบคุณสำหรับความคิดเห็นที่ดีของคุณ @MarkAmery! ฉันซาบซึ้งจริงๆ
simhumileco

1
@simhumileco เหตุใดจึงมีวิธีแก้ไขปัญหาที่ดีที่สุด (ถูกต้อง) ล่าสุด
AMC

@AMC เพราะก่อนอื่นฉันต้องการแสดงวิธีที่ง่ายที่สุดและเพื่อความสอดคล้องของการให้เหตุผล
simhumileco

นอกจากนี้ฉันหวังว่าคำตอบของฉันจะทำให้สั้นและง่ายต่อการอ่าน
simhumileco

4

ใช้สิ่งนี้:

import pandas as pd
data = pd.read_csv(filename) # You can also add parameters such as header, sep, etc.
array = data.values

dataเป็นประเภท dataframe และใช้ค่าในการรับ ndarray array.tolist()นอกจากนี้คุณยังสามารถได้รับรายชื่อโดยใช้


pandas.read_csv()สำหรับอ่านข้อมูลCSVเป็นวิธีที่เหมาะสมที่นี่?
AMC

4

โครงร่างและบทสรุป

ด้วยการfilenameจัดการไฟล์จากPath(filename)วัตถุหรือโดยตรงด้วยopen(filename) as fทำอย่างใดอย่างหนึ่งต่อไปนี้:

  • list(fileinput.input(filename))
  • ใช้with path.open() as f, โทรf.readlines()
  • list(f)
  • path.read_text().splitlines()
  • path.read_text().splitlines(keepends=True)
  • ย้ำกว่าfileinput.inputหรือfและlist.appendแต่ละบรรทัดในเวลา
  • ส่งผ่านfไปยังขอบเขตlist.extendวิธีการที่
  • ใช้fในรายการความเข้าใจ

ฉันอธิบายถึงกรณีการใช้งานสำหรับแต่ละด้านล่าง

ใน Python ฉันจะอ่านไฟล์ทีละบรรทัดได้อย่างไร

นี่เป็นคำถามที่ยอดเยี่ยม ก่อนอื่นมาสร้างข้อมูลตัวอย่าง:

from pathlib import Path
Path('filename').write_text('foo\nbar\nbaz')

วัตถุไฟล์เป็นตัววนซ้ำขี้เกียจดังนั้นเพียงแค่วนซ้ำมัน

filename = 'filename'
with open(filename) as f:
    for line in f:
        line # do something with the line

หรือหากคุณมีไฟล์หลายไฟล์ให้ใช้fileinput.inputตัววนซ้ำตัวเอียงอื่น ด้วยไฟล์เดียว:

import fileinput

for line in fileinput.input(filename): 
    line # process the line

หรือสำหรับหลายไฟล์ให้ส่งผ่านรายชื่อไฟล์:

for line in fileinput.input([filename]*2): 
    line # process the line

อีกครั้งfและfileinput.inputเหนือทั้งคู่เป็น / ส่งคืนตัววนซ้ำ คุณสามารถใช้ตัววนซ้ำได้เพียงครั้งเดียวดังนั้นเพื่อให้รหัสการทำงานในขณะที่หลีกเลี่ยงการใช้คำฟุ่มเฟื่อยฉันจะใช้ตัวย่อfileinput.input(filename)ที่ apropos จากที่นี่เล็กน้อย

ใน Python ฉันจะอ่านไฟล์ทีละบรรทัดในรายการได้อย่างไร

อ่า แต่คุณต้องการมันอยู่ในรายการด้วยเหตุผลบางอย่าง? ฉันจะหลีกเลี่ยงสิ่งนั้นถ้าเป็นไปได้ แต่ถ้าคุณยืนยัน ... เพียงส่งผลลัพธ์ของfileinput.input(filename)ไปที่list:

list(fileinput.input(filename))

อีกคำตอบโดยตรงคือการโทรf.readlinesซึ่งจะส่งคืนเนื้อหาของไฟล์ (สูงสุดไม่เกินhintจำนวนอักขระดังนั้นคุณสามารถทำได้แบ่งออกเป็นหลายรายการในแบบนั้น)

คุณสามารถไปที่วัตถุไฟล์นี้ได้สองวิธี วิธีหนึ่งคือการส่งชื่อไฟล์ไปยังopenตัวเครื่อง:

filename = 'filename'

with open(filename) as f:
    f.readlines()

หรือใช้วัตถุ Path ใหม่จากpathlibโมดูล (ซึ่งฉันได้กลายเป็นที่ชื่นชอบและจะใช้จากที่นี่บน):

from pathlib import Path

path = Path(filename)

with path.open() as f:
    f.readlines()

list จะใช้ตัววนซ้ำไฟล์และส่งคืนรายการซึ่งเป็นวิธีที่ค่อนข้างตรงเช่นกัน:

with path.open() as f:
    list(f)

หากคุณไม่สนใจที่จะอ่านข้อความทั้งหมดในหน่วยความจำในรูปแบบสตริงเดียวก่อนที่จะแยกคุณสามารถทำสิ่งนี้เป็นหนึ่งซับกับPathวัตถุและsplitlines()วิธีการสตริง โดยค่าเริ่มต้นsplitlinesจะลบบรรทัดใหม่:

path.read_text().splitlines()

หากคุณต้องการขึ้นบรรทัดใหม่ให้ผ่านkeepends=True:

path.read_text().splitlines(keepends=True)

ฉันต้องการอ่านไฟล์ทีละบรรทัดและต่อท้ายแต่ละบรรทัดต่อท้ายรายการ

ตอนนี้มันค่อนข้างโง่ที่จะถามเพราะเราได้แสดงให้เห็นผลลัพธ์สุดท้ายได้อย่างง่ายดายด้วยหลายวิธี แต่คุณอาจจำเป็นต้องกรองหรือดำเนินการในบรรทัดในขณะที่คุณทำรายการของคุณดังนั้นขออารมณ์ขันนี้

การใช้list.appendจะช่วยให้คุณสามารถกรองหรือทำงานในแต่ละบรรทัดก่อนที่คุณจะต่อท้าย:

line_list = []
for line in fileinput.input(filename):
    line_list.append(line)

line_list

การใช้list.extendจะค่อนข้างตรงไปกว่าและอาจมีประโยชน์หากคุณมีรายการที่มีอยู่ก่อนหน้า:

line_list = []
line_list.extend(fileinput.input(filename))
line_list

หรือมากกว่าปกติเราสามารถใช้ list comprehension และแมปและกรองภายในถ้าต้องการ:

[line for line in fileinput.input(filename)]

หรือมากกว่านั้นโดยตรงเพื่อปิดวงกลมเพียงแค่ส่งไปที่รายการเพื่อสร้างรายการใหม่โดยตรงโดยไม่ต้องใช้งานบนบรรทัด:

list(fileinput.input(filename))

ข้อสรุป

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

นั่นคือต้องการหรือfileinput.inputwith path.open() as f


4

ในกรณีที่มีบรรทัดว่างในเอกสารฉันชอบอ่านในเนื้อหาและส่งผ่านfilterเพื่อป้องกันองค์ประกอบสตริงว่างเปล่า

with open(myFile, "r") as f:
    excludeFileContent = list(filter(None, f.read().splitlines()))

1
นี่คือเสียงไพเราะระวังตัวด้วย
AMC

3

คุณสามารถใช้คำสั่ง loadtxt ใน NumPy การตรวจสอบเงื่อนไขน้อยกว่า genfromtxt ดังนั้นจึงอาจเร็วกว่า

import numpy
data = numpy.loadtxt(filename, delimiter="\n")

2

ฉันชอบที่จะใช้ดังต่อไปนี้ อ่านบรรทัดทันที

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

หรือใช้ความเข้าใจในรายการ:

contents = [line.strip() for line in open(filepath, 'r').readlines()]

2
ไม่จำเป็นต้องreadlines()มีแม้กระทั่งการลงโทษหน่วยความจำ คุณสามารถลบออกได้ง่าย ๆ เนื่องจากการวนซ้ำไฟล์ (text) จะให้แต่ละบรรทัด
Eric O Lebigot

2
คุณควรใช้withคำสั่งเพื่อเปิด (และปิดโดยนัย) ไฟล์
Aran-Fey

2

ฉันจะลองวิธีที่กล่าวถึงด้านล่าง dummy.txtไฟล์ตัวอย่างที่ผมใช้มีชื่อ คุณสามารถค้นหาไฟล์ที่นี่ ฉันเข้าใจว่าไฟล์อยู่ในไดเรกทอรีเดียวกับรหัส (คุณสามารถเปลี่ยนfpathเพื่อรวมชื่อไฟล์และเส้นทางโฟลเดอร์ที่เหมาะสม)

lstในทั้งสองตัวอย่างที่ระบุไว้ด้านล่างรายการที่คุณต้องการจะได้รับจาก

1. > วิธีแรก :

fpath = 'dummy.txt'
with open(fpath, "r") as f: lst = [line.rstrip('\n \t') for line in f]

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2. >ในวิธีที่สองเราสามารถใช้โมดูลcsv.readerจาก Python Standard Library :

import csv
fpath = 'dummy.txt'
with open(fpath) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter='   ')
    lst = [row[0] for row in csv_reader] 

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

คุณสามารถใช้หนึ่งในสองวิธีนี้ เวลาที่ใช้ในการสร้างlstเกือบเท่ากันในสองวิธี


1
อะไรคือข้อดีของวิธีการที่สอง? เหตุใดจึงต้องเรียกใช้ไลบรารีเพิ่มเติมซึ่งเพิ่มในกรณีที่เป็นขอบ (ตัวคั่นและเครื่องหมายคำพูด)
Charlie Harding

เป็นสิ่งที่delimiter=' 'โต้แย้งหรือไม่?
AMC

2

นี่คืองูหลาม (3) ผู้ช่วยห้องสมุดชั้นเรียนที่ผมใช้ในการลดความซับซ้อนของไฟล์ I / O:

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

จากนั้นคุณจะใช้FileIO.linesฟังก์ชันเช่นนี้:

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

โปรดจำไว้ว่าพารามิเตอร์mode( "r"ตามค่าเริ่มต้น) และfilter_fn(ตรวจสอบบรรทัดว่างเปล่าตามค่าเริ่มต้น) เป็นตัวเลือก

คุณยังสามารถลบread, writeและdeleteวิธีการและเพียงแค่ปล่อยให้หรือแม้กระทั่งทำให้มันกลายเป็นวิธีการที่เรียกว่าแยกต่างหากFileIO.linesread_lines


มันlines = FileIO.lines(path)ง่ายกว่าwith open(path) as f: lines = f.readlines()การจัดแสดงตัวช่วยนี้หรือไม่ คุณกำลังบันทึกเช่นเดียวกับ 17 ตัวอักษรต่อการโทร (และส่วนใหญ่สำหรับเหตุผลด้านประสิทธิภาพและความจำคุณจะต้องวนลูปวัตถุไฟล์โดยตรงแทนที่จะอ่านบรรทัดลงในรายการต่อไปดังนั้นคุณจะไม่ต้องการใช้มันบ่อยๆ!) ฉัน บ่อยครั้งที่แฟน ๆ ของการสร้างฟังก์ชั่นยูทิลิตี้เล็ก ๆ น้อย ๆ แต่อันนี้ฉันรู้สึกเหมือนมันเป็นเพียงการสร้างวิธีการใหม่ในการเขียนสิ่งที่สั้นและง่ายด้วยไลบรารีมาตรฐานที่ให้เรา
Mark Amery

นอกจากสิ่งที่ @MarkAmery พูดแล้วทำไมต้องใช้คลาสนี้
AMC

1

เวอร์ชันของบรรทัดคำสั่ง

#!/bin/python3
import os
import sys
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
filename = dname + sys.argv[1]
arr = open(filename).read().split("\n") 
print(arr)

ทำงานด้วย:

python3 somefile.py input_file_name.txt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.