ฉันจะอ่านไฟล์ทุกบรรทัดใน Python และเก็บแต่ละบรรทัดเป็นองค์ประกอบในรายการได้อย่างไร
ฉันต้องการอ่านไฟล์ทีละบรรทัดและต่อท้ายแต่ละบรรทัดต่อท้ายรายการ
ฉันจะอ่านไฟล์ทุกบรรทัดใน Python และเก็บแต่ละบรรทัดเป็นองค์ประกอบในรายการได้อย่างไร
ฉันต้องการอ่านไฟล์ทีละบรรทัดและต่อท้ายแต่ละบรรทัดต่อท้ายรายการ
คำตอบ:
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]
readlines()
ไม่ได้มีประสิทธิภาพมากอย่างที่มันสามารถส่งผลในMemoryError ในกรณีนี้จะเป็นการดีกว่าที่จะวนซ้ำไฟล์ที่ใช้for line in f:
และทำงานกับline
ตัวแปรแต่ละตัว
.rstrip()
จะทำงานได้เร็วขึ้นเล็กน้อยหากคุณเปิดช่องว่างจากปลายเส้น
with open(filename) as f: content = [i.strip() for i in f.readlines()]
ดูอินพุตและ Ouput :
with open('filename') as f:
lines = f.readlines()
หรือลอกอักขระขึ้นบรรทัดใหม่:
with open('filename') as f:
lines = [line.rstrip() for line in f]
f.read().splitlines()
ซึ่งจะลบบรรทัดใหม่
for line in open(filename)
ปลอดภัยไหม นั่นคือไฟล์จะถูกปิดโดยอัตโนมัติหรือไม่
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]
ถ้าฉันเขียนด้วยวิธีนี้ฉันจะปิดไฟล์หลังจากอ่านได้อย่างไร
open
โดยไม่มีตัวจัดการบริบท (หรือวิธีอื่นที่รับประกันได้ว่าจะปิด) สิ่งนี้ไม่ใช่กรณีเหล่านี้จริง ๆ - เมื่อวัตถุไม่มีการอ้างอิงเพิ่มเติม ไปมันจะถูกเก็บรวบรวมขยะและไฟล์ที่ปิดซึ่งควรจะเกิดขึ้นทันทีในข้อผิดพลาดหรือไม่เมื่อรายการความเข้าใจจะเสร็จสิ้นการประมวลผล
ชัดเจนกว่าที่จำเป็น แต่ทำในสิ่งที่คุณต้องการ
with open("file.txt") as file_in:
lines = []
for line in file_in:
lines.append(line)
array
แต่อาจมีสถานการณ์อื่น) แน่นอนว่าสำหรับไฟล์ขนาดใหญ่วิธีนี้อาจช่วยลดปัญหาได้
สิ่งนี้จะให้ผลเป็น "อาร์เรย์" ของบรรทัดจากไฟล์
lines = tuple(open(filename, 'r'))
open
ส่งคืนไฟล์ที่สามารถวนซ้ำได้ เมื่อคุณวนซ้ำไฟล์คุณจะได้รับบรรทัดจากไฟล์นั้น tuple
สามารถใช้ตัววนซ้ำและยกตัวอย่างอินสแตนซ์ tuple ให้คุณจากตัววนซ้ำที่คุณให้ lines
คือ tuple ที่สร้างจากบรรทัดของไฟล์
lines = open(filename).read().split('\n')
แทน
lines = open(filename).read().splitlines()
สะอาดขึ้นเล็กน้อยและฉันเชื่อว่ามันยังจัดการกับจุดสิ้นสุดของ DOS ได้ดีกว่า
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 ครั้ง โซลูชันของฉันโปรดปรานพื้นที่มากกว่าความเร็วเมื่อไม่ทราบความต้องการความไม่แน่นอน
ถ้าคุณต้องการ\n
รวม:
with open(fname) as f:
content = f.readlines()
หากคุณไม่ต้องการ\n
รวม:
with open(fname) as f:
content = f.read().splitlines()
ตามวิธีการของ 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
คุณสามารถทำสิ่งต่อไปนี้ตามที่ได้รับการแนะนำ:
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 นี่คือวิธีการแยกวิเคราะห์ทั่วไปที่จะทำงาน
open('file_path', 'r+')
ข้อมูลลงในรายการ
สมมติว่าเรามีไฟล์ข้อความที่มีข้อมูลเหมือนในบรรทัดต่อไปนี้
เนื้อหาไฟล์ข้อความ:
line 1
line 2
line 3
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"
ต้อง?
read().splitlines()
Python ให้บริการแก่คุณ: เป็นเพียงreadlines()
(ซึ่งอาจเร็วกว่าเนื่องจากมีความสิ้นเปลืองน้อยกว่า)
read().splitlines()
และreadlines()
ไม่สร้างผลลัพธ์เดียวกัน คุณแน่ใจหรือว่าพวกเขาเทียบเท่า
หากต้องการอ่านไฟล์ลงในรายการคุณต้องทำสามสิ่ง:
โชคดีที่ 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\n
Windows หรือ\r
Mac เป็นบรรทัดใหม่ก็ได้) หากคุณไม่ต้องการให้คุณสามารถลบอักขระสุดท้าย (หรืออักขระสองตัวสุดท้ายบน 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
เมื่อเปิดไฟล์เพราะคุณไม่จำเป็นต้องปิดไฟล์เองและจะปิดไฟล์แม้ว่าจะมีข้อยกเว้นเกิดขึ้นfile
for line in the_file_object:
วัตถุสนับสนุนโปรโตคอลซ้ำเพื่ออ่านไฟล์บรรทัดโดยบรรทัดเป็นง่ายๆเป็นreadlines()
แต่ถ้าคุณต้องการประมวลผลบรรทัดก่อนที่จะเก็บไว้ในรายการฉันจะแนะนำรายการเข้าใจง่ายวิธีที่สะอาดและเป็นระบบในการอ่านบรรทัดของไฟล์ไปสู่รายการ
ก่อนอื่นคุณควรเน้นที่การเปิดไฟล์ของคุณและอ่านเนื้อหาในวิธีที่มีประสิทธิภาพและรวดเร็ว นี่คือตัวอย่างของวิธีที่ฉันไม่ชอบ:
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]
['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ã.
เปิดตัวใน Python 3.4 pathlib
มีวิธีที่สะดวกมากในการอ่านข้อความจากไฟล์ดังนี้:
from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()
(การsplitlines
เรียกเป็นสิ่งที่เปลี่ยนจากสตริงที่มีเนื้อหาทั้งหมดของไฟล์เป็นรายการของบรรทัดในไฟล์)
pathlib
มีสิ่งอำนวยความสะดวกมากมายในนั้น read_text
เป็นคนดีและรัดกุมและคุณไม่ต้องกังวลเกี่ยวกับการเปิดและปิดไฟล์ หากสิ่งที่คุณต้องทำเกี่ยวกับไฟล์นั้นถูกอ่านทั้งหมดในครั้งเดียวมันเป็นตัวเลือกที่ดี
นี่คืออีกหนึ่งตัวเลือกโดยใช้รายการความเข้าใจในไฟล์;
lines = [line.rstrip() for line in open('file.txt')]
นี่ควรเป็นวิธีที่มีประสิทธิภาพมากขึ้นเนื่องจากงานส่วนใหญ่ทำในล่าม Python
rstrip()
อาจตัดช่องว่างต่อท้ายทั้งหมดไม่เพียง แต่\n
; .rstrip('\n')
ใช้
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)
คุณจะได้รับผลลัพธ์เดียวกัน
อ่านและเขียนไฟล์ข้อความด้วย 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
การเขียน / อ่านไฟล์ขั้นสูงเพิ่มเติม
สำหรับแอปพลิเคชันของคุณข้อมูลต่อไปนี้อาจสำคัญ:
ดูเพิ่มเติม: การเปรียบเทียบรูปแบบการจัดลำดับข้อมูล
ในกรณีที่คุณกำลังค่อนข้างมองหาวิธีที่จะทำให้แฟ้มการกำหนดค่าที่คุณอาจต้องการที่จะอ่านบทความสั้น ๆ ของฉันแฟ้มการกำหนดค่าในหลาม
ตัวเลือกอื่นคือnumpy.genfromtxt
ตัวอย่างเช่น:
import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")
สิ่งนี้จะทำให้data
อาร์เรย์ NumPy มีแถวมากเท่ากับที่อยู่ในไฟล์ของคุณ
หากคุณต้องการอ่านไฟล์จากบรรทัดคำสั่งหรือจาก 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
วิธีที่ง่ายที่สุดที่จะทำ
วิธีง่ายๆคือ:
ในหนึ่งบรรทัดที่จะให้:
lines = open('C:/path/file.txt').read().splitlines()
อย่างไรก็ตามวิธีนี้ค่อนข้างไม่มีประสิทธิภาพเนื่องจากจะเก็บเนื้อหา 2 รุ่นในหน่วยความจำ (อาจไม่ใช่ปัญหาใหญ่สำหรับไฟล์ขนาดเล็ก แต่ยังคงมี) [ขอบคุณ Mark Amery]
มี 2 วิธีง่ายกว่า:
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')]
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()
) ในหน่วยความจำพร้อมกัน
เพียงใช้ฟังก์ชั่น splitlines () นี่คือตัวอย่าง
inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3
ในผลลัพธ์คุณจะมีรายการของบรรทัด
.readlines()
หน่วยความจำที่ไม่มีประสิทธิภาพเทียบกับการใช้ สิ่งนี้ทำให้สำเนาสองไฟล์ของเนื้อหาในหน่วยความจำพร้อมกัน (หนึ่งเป็นสตริงขนาดใหญ่เดียวหนึ่งเป็นรายการของบรรทัด)
หากคุณต้องการเผชิญหน้ากับไฟล์ที่มีขนาดใหญ่ / ใหญ่และต้องการอ่านเร็วขึ้น (ลองจินตนาการว่าคุณอยู่ในการแข่งขันการเข้ารหัส 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)
process(line)
เป็นฟังก์ชันที่คุณต้องใช้ในการประมวลผลข้อมูล ตัวอย่างเช่นแทนที่จะเป็นบรรทัดนั้นถ้าคุณใช้print(line)
มันจะพิมพ์แต่ละบรรทัดจาก lines_buffer
lines = list(open('filename'))
หรือ
lines = tuple(open('filename'))
หรือ
lines = set(open('filename'))
ในกรณีที่มี set
เราต้องจำไว้ว่าเราไม่มีคำสั่งซื้อที่สงวนไว้และกำจัดบรรทัดที่ซ้ำกัน
เนื่องจากคุณไม่ได้โทรหา
.close
วัตถุไฟล์หรือใช้with
คำสั่งในการใช้งานPythonบางไฟล์อาจไม่ได้ปิดหลังจากอ่านและกระบวนการของคุณจะรั่วไหลที่จับเปิดไฟล์ไฟล์อาจไม่ได้รับหลังจากปิดการอ่านและกระบวนการของคุณจะรั่วไหลจับเปิดแฟ้มในCPython (การใช้งานPythonปกติที่คนส่วนใหญ่ใช้) นี่ไม่ใช่ปัญหาเนื่องจากวัตถุไฟล์จะได้รับการรวบรวมขยะทันทีและจะปิดไฟล์ แต่โดยทั่วไปแล้วถือว่าเป็นการปฏิบัติที่ดีที่สุดในการทำสิ่งต่อไปนี้ :
with open('filename') as f: lines = list(f)
เพื่อให้แน่ใจว่าไฟล์จะถูกปิดไม่ว่าคุณจะใช้Python แบบใด
.close
วัตถุไฟล์หรือใช้with
คำสั่งในการใช้งาน Python บางไฟล์อาจไม่ได้ปิดหลังจากอ่านและกระบวนการของคุณจะรั่วไหลที่จับเปิดไฟล์ ใน CPython (การใช้งาน Python ปกติที่คนส่วนใหญ่ใช้) นี่ไม่ใช่ปัญหาเนื่องจากวัตถุไฟล์จะได้รับการรวบรวมขยะทันทีและจะปิดไฟล์ แต่โดยทั่วไปถือว่าเป็นการปฏิบัติที่ดีที่สุดwith open('filename') as f: lines = list(f)
เพื่อให้แน่ใจว่า ไฟล์ถูกปิดโดยไม่คำนึงถึงการใช้งาน Python ที่คุณใช้
ใช้สิ่งนี้:
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เป็นวิธีที่เหมาะสมที่นี่?
ด้วยการ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.input
with path.open() as f
ในกรณีที่มีบรรทัดว่างในเอกสารฉันชอบอ่านในเนื้อหาและส่งผ่านfilter
เพื่อป้องกันองค์ประกอบสตริงว่างเปล่า
with open(myFile, "r") as f:
excludeFileContent = list(filter(None, f.read().splitlines()))
คุณสามารถใช้คำสั่ง loadtxt ใน NumPy การตรวจสอบเงื่อนไขน้อยกว่า genfromtxt ดังนั้นจึงอาจเร็วกว่า
import numpy
data = numpy.loadtxt(filename, delimiter="\n")
ฉันชอบที่จะใช้ดังต่อไปนี้ อ่านบรรทัดทันที
contents = []
for line in open(filepath, 'r').readlines():
contents.append(line.strip())
หรือใช้ความเข้าใจในรายการ:
contents = [line.strip() for line in open(filepath, 'r').readlines()]
readlines()
มีแม้กระทั่งการลงโทษหน่วยความจำ คุณสามารถลบออกได้ง่าย ๆ เนื่องจากการวนซ้ำไฟล์ (text) จะให้แต่ละบรรทัด
with
คำสั่งเพื่อเปิด (และปิดโดยนัย) ไฟล์
ฉันจะลองวิธีที่กล่าวถึงด้านล่าง 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
เกือบเท่ากันในสองวิธี
delimiter=' '
โต้แย้งหรือไม่?
นี่คืองูหลาม (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.lines
read_lines
lines = FileIO.lines(path)
ง่ายกว่าwith open(path) as f: lines = f.readlines()
การจัดแสดงตัวช่วยนี้หรือไม่ คุณกำลังบันทึกเช่นเดียวกับ 17 ตัวอักษรต่อการโทร (และส่วนใหญ่สำหรับเหตุผลด้านประสิทธิภาพและความจำคุณจะต้องวนลูปวัตถุไฟล์โดยตรงแทนที่จะอ่านบรรทัดลงในรายการต่อไปดังนั้นคุณจะไม่ต้องการใช้มันบ่อยๆ!) ฉัน บ่อยครั้งที่แฟน ๆ ของการสร้างฟังก์ชั่นยูทิลิตี้เล็ก ๆ น้อย ๆ แต่อันนี้ฉันรู้สึกเหมือนมันเป็นเพียงการสร้างวิธีการใหม่ในการเขียนสิ่งที่สั้นและง่ายด้วยไลบรารีมาตรฐานที่ให้เรา
#!/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
file.readlines()
ในfor
-loop วัตถุไฟล์นั้นก็เพียงพอแล้ว:lines = [line.rstrip('\n') for line in file]