ฉันกำลังใช้ลูป for เพื่ออ่านไฟล์ แต่ฉันต้องการอ่านเฉพาะบรรทัดพูดบรรทัดที่ 26 และ # 30 มีคุณสมบัติในตัวเพื่อให้บรรลุสิ่งนี้หรือไม่?
ขอบคุณ
ฉันกำลังใช้ลูป for เพื่ออ่านไฟล์ แต่ฉันต้องการอ่านเฉพาะบรรทัดพูดบรรทัดที่ 26 และ # 30 มีคุณสมบัติในตัวเพื่อให้บรรลุสิ่งนี้หรือไม่?
ขอบคุณ
คำตอบ:
หากไฟล์ที่จะอ่านมีขนาดใหญ่และคุณไม่ต้องการอ่านไฟล์ทั้งหมดในหน่วยความจำพร้อมกัน:
fp = open("file")
for i, line in enumerate(fp):
if i == 25:
# 26th line
elif i == 29:
# 30th line
elif i > 29:
break
fp.close()
โปรดทราบว่าi == n-1
สำหรับn
บรรทัดที่
ใน Python 2.6 หรือใหม่กว่า:
with open("file") as fp:
for i, line in enumerate(fp):
if i == 25:
# 26th line
elif i == 29:
# 30th line
elif i > 29:
break
enumerate(x)
ใช้x.next
ดังนั้นจึงไม่จำเป็นต้องใช้ไฟล์ทั้งหมดในหน่วยความจำ
big file
เหตุผลที่ใช้สำหรับวงผมไม่คิดว่าคุณเข้าใจความหมายของ การวนซ้ำจะใช้เวลาหลายปีกว่าจะถึงดัชนี
คำตอบอย่างรวดเร็ว:
f=open('filename')
lines=f.readlines()
print lines[25]
print lines[29]
หรือ:
lines=[25, 29]
i=0
f=open('filename')
for line in f:
if i in lines:
print i
i+=1
มีโซลูชันที่หรูหรากว่าสำหรับการแยกหลายบรรทัด: linecache (ความอนุเคราะห์ของ"หลาม: วิธีการข้ามไปที่บรรทัดเฉพาะในไฟล์ข้อความขนาดใหญ่?"คำถาม stackoverflow.com ก่อนหน้านี้)
การอ้างถึงเอกสารหลามที่ลิงก์ด้านบน:
>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'
เปลี่ยน 4
หมายเลขบรรทัดที่คุณต้องการและคุณเปิด โปรดทราบว่า 4 จะนำบรรทัดที่ห้าเนื่องจากการนับเป็นศูนย์
หากไฟล์อาจมีขนาดใหญ่มากและทำให้เกิดปัญหาเมื่ออ่านในหน่วยความจำอาจเป็นคำแนะนำที่ดีที่@ Alok แนะนำและใช้ enumerate ()()
สรุป:
fileobject.readlines()
หรือfor line in fileobject
เป็นวิธีแก้ปัญหาอย่างรวดเร็วสำหรับไฟล์ขนาดเล็กlinecache
สำหรับโซลูชันที่หรูหรากว่าซึ่งจะค่อนข้างเร็วสำหรับการอ่านไฟล์จำนวนมากenumerate()
สำหรับไฟล์ซึ่งอาจจะมีขนาดใหญ่มากและจะไม่พอดีในหน่วยความจำ โปรดทราบว่าการใช้วิธีนี้อาจช้าเพราะอ่านไฟล์ตามลำดับlinecache
โมดูลและดูเหมือนว่าจะอ่านไฟล์ทั้งหมดในหน่วยความจำ ดังนั้นหากการเข้าถึงแบบสุ่มสำคัญกว่าการปรับขนาดให้เหมาะสมlinecache
เป็นวิธีที่ดีที่สุด
linecache
ตอนนี้ดูเหมือนว่าจะทำงานเฉพาะกับไฟล์ต้นฉบับของไพ ธ อน
linecache.getlines('/etc/passwd')[0:4]
อ่านในบรรทัดแรก, สอง, สามและสี่
วิธีที่รวดเร็วและกะทัดรัดอาจเป็น:
def picklines(thefile, whatlines):
return [x for i, x in enumerate(thefile) if i in whatlines]
สิ่งนี้ยอมรับออบเจ็กต์ที่มีลักษณะเหมือนไฟล์ใด ๆthefile
(ปล่อยให้ผู้โทรทราบว่าควรจะเปิดจากไฟล์ดิสก์หรือผ่านทางซ็อกเก็ตหรือสตรีมไฟล์อื่น ๆ ) และชุดของดัชนีบรรทัดตามศูนย์whatlines
และส่งกลับค่า รายการที่มีหน่วยความจำต่ำและความเร็วที่เหมาะสม หากจำนวนบรรทัดที่จะส่งคืนมีขนาดใหญ่มากคุณอาจต้องการเครื่องกำเนิดไฟฟ้า:
def yieldlines(thefile, whatlines):
return (x for i, x in enumerate(thefile) if i in whatlines)
ซึ่งโดยทั่วไปดีสำหรับการวนรอบเท่านั้น - โปรดทราบว่าความแตกต่างเพียงอย่างเดียวนั้นมาจากการใช้การปัดเศษมากกว่าวงเล็บเหลี่ยมในreturn
คำสั่งทำให้เข้าใจรายการและนิพจน์เครื่องกำเนิดไฟฟ้าตามลำดับ
ทราบเพิ่มเติมว่าแม้จะมีการกล่าวถึง "เส้น" และ "ไฟล์" ฟังก์ชั่นเหล่านี้มีมากมากมากขึ้นทั่วไป - พวกเขาจะทำงานในใด ๆ iterable ไม่ว่าจะเป็นเปิดไฟล์หรืออื่น ๆ กลับรายการ (หรือเครื่องกำเนิดไฟฟ้า) ของรายการ ขึ้นอยู่กับหมายเลขรายการก้าวหน้าของพวกเขา ดังนั้นฉันขอแนะนำให้ใช้ชื่อสามัญที่เหมาะสมกว่า ;-)
whatlines
ควรจะเป็นset
เพราะif i in whatlines
จะทำงานได้เร็วขึ้นด้วยชุดมากกว่ารายการ (เรียงลำดับ) ฉันไม่ได้สังเกตมันก่อนและคิดค้นวิธีการแก้ปัญหาที่น่าเกลียดของตัวเองด้วยรายการที่เรียงลำดับ (ซึ่งฉันไม่ต้องสแกนรายการทุกครั้งในขณะที่if i in whatlines
ทำแบบนั้น) แต่ความแตกต่างของประสิทธิภาพนั้นเล็กน้อย (กับข้อมูลของฉัน) และสิ่งนี้ วิธีการแก้ปัญหามีความสง่างามมากขึ้น
เพื่อเสนอวิธีแก้ปัญหาอื่น:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
ฉันหวังว่านี่จะง่ายและรวดเร็ว :)
ถ้าคุณต้องการบรรทัด 7
บรรทัด = open ("file.txt", "r"). readlines () [7]
close()
เปิดไฟล์ด้วยวิธีนี้ได้อย่างไร?
เพื่อความสมบูรณ์นี่คืออีกหนึ่งทางเลือก
เริ่มจากนิยามของpython docsกันดีกว่า:
ชิ้นมักจะมีชิ้นส่วนของลำดับ ชิ้นถูกสร้างขึ้นโดยใช้สัญกรณ์ห้อย [] กับ colons ระหว่างตัวเลขเมื่อได้รับหลายอย่างเช่นใน variable_name [1: 3: 5] เครื่องหมายวงเล็บ (ห้อย) ใช้วัตถุชิ้นภายใน (หรือในรุ่นเก่ากว่า, __getslice __ () และ __setslice __ ())
แม้ว่าสัญกรณ์สไลซ์จะไม่สามารถใช้ได้โดยตรงกับตัววนซ้ำโดยทั่วไปitertools
แพ็คเกจบรรจุฟังก์ชันการแทนที่
from itertools import islice
# print the 100th line
with open('the_file') as lines:
for line in islice(lines, 99, 100):
print line
# print each third line until 100
with open('the_file') as lines:
for line in islice(lines, 0, 100, 3):
print line
ข้อดีเพิ่มเติมของฟังก์ชั่นคือมันไม่ได้อ่านตัววนซ้ำจนกว่าจะสิ้นสุด ดังนั้นคุณสามารถทำสิ่งที่ซับซ้อนมากขึ้น:
with open('the_file') as lines:
# print the first 100 lines
for line in islice(lines, 100):
print line
# then skip the next 5
for line in islice(lines, 5):
pass
# print the rest
for line in lines:
print line
และเพื่อตอบคำถามเดิม:
# how to read lines #26 and #30
In [365]: list(islice(xrange(1,100), 25, 30, 4))
Out[365]: [26, 30]
การอ่านไฟล์เป็นไปอย่างรวดเร็วอย่างไม่น่าเชื่อ การอ่านไฟล์ 100MB ใช้เวลาน้อยกว่า 0.1 วินาที (ดูบทความการอ่านและเขียนไฟล์ของฉันด้วย Python ) ดังนั้นคุณควรอ่านให้ครบถ้วนและทำงานกับบรรทัดเดียว
คำตอบส่วนใหญ่ที่นี่ทำไม่ผิด แต่สไตล์ไม่ดี การเปิดไฟล์ควรทำด้วยเสมอwith
เพราะทำให้แน่ใจว่าไฟล์นั้นถูกปิดอีกครั้ง
ดังนั้นคุณควรทำเช่นนี้:
with open("path/to/file.txt") as f:
lines = f.readlines()
print(lines[26]) # or whatever you want to do with this line
print(lines[30]) # or whatever you want to do with this line
หากคุณมีไฟล์จำนวนมากและการใช้หน่วยความจำเป็นเรื่องที่กังวลคุณสามารถประมวลผลทีละบรรทัด:
with open("path/to/file.txt") as f:
for i, line in enumerate(f):
pass # process line i
สิ่งเหล่านี้น่ารัก แต่ก็สามารถทำได้ง่ายกว่า:
start = 0 # some starting index
end = 5000 # some ending index
filename = 'test.txt' # some file we want to use
with open(filename) as fh:
data = fin.readlines()[start:end]
print(data)
นั่นจะใช้การแบ่งรายการแบบง่ายๆโหลดไฟล์ทั้งหมด แต่ระบบส่วนใหญ่จะลดการใช้หน่วยความจำอย่างเหมาะสมมันเร็วกว่าวิธีการส่วนใหญ่ที่ระบุด้านบนและทำงานกับไฟล์ข้อมูล 10G + ของฉัน โชคดี!
คุณสามารถทำการเรียก()โทรซึ่งวางตำแหน่งหัวอ่านของคุณไปยังไบต์ที่ระบุภายในไฟล์ สิ่งนี้จะไม่ช่วยคุณจนกว่าคุณจะรู้จำนวนไบต์ (ตัวอักษร) ที่เขียนในไฟล์ก่อนที่คุณจะอ่าน บางทีไฟล์ของคุณมีการจัดรูปแบบอย่างเข้มงวด (แต่ละบรรทัดคือ X จำนวนไบต์?) หรือคุณสามารถนับจำนวนอักขระด้วยตัวคุณเอง (อย่าลืมใส่อักขระที่มองไม่เห็นเช่นตัวแบ่งบรรทัด) หากคุณต้องการเร่งความเร็ว
มิฉะนั้นคุณจะต้องอ่านทุกบรรทัดก่อนถึงบรรทัดที่คุณต้องการตามหนึ่งในวิธีแก้ปัญหามากมายที่เสนอไว้แล้วที่นี่
หากไฟล์ข้อความขนาดใหญ่ของคุณมีfile
โครงสร้างที่ดีอย่างเข้มงวด (หมายถึงทุกบรรทัดมีความยาวเท่ากันl
) คุณสามารถใช้สำหรับn
บรรทัดที่ -th
with open(file) as f:
f.seek(n*l)
line = f.readline()
last_pos = f.tell()
ข้อจำกัดความรับผิดชอบนี่ใช้งานได้กับไฟล์ที่มีความยาวเท่ากัน!
เกี่ยวกับสิ่งนี้:
>>> with open('a', 'r') as fin: lines = fin.readlines()
>>> for i, line in enumerate(lines):
if i > 30: break
if i == 26: dox()
if i == 30: doy()
หากคุณไม่สนใจการนำเข้าไฟล์ป้อนข้อมูลจะทำสิ่งที่คุณต้องการ (นี่คือคุณสามารถอ่านหมายเลขบรรทัดของบรรทัดปัจจุบัน)
def getitems(iterable, items):
items = list(items) # get a list from any iterable and make our own copy
# since we modify it
if items:
items.sort()
for n, v in enumerate(iterable):
if n == items[0]:
yield v
items.pop(0)
if not items:
break
print list(getitems(open("/usr/share/dict/words"), [25, 29]))
# ['Abelson\n', 'Abernathy\n']
# note that index 25 is the 26th item
ผมชอบวิธีนี้เพราะมันมากขึ้นวัตถุประสงค์ทั่วไปคือคุณสามารถใช้ในแฟ้มผลการf.readlines()
บนStringIO
วัตถุสิ่ง:
def read_specific_lines(file, lines_to_read):
"""file is any iterable; lines_to_read is an iterable containing int values"""
lines = set(lines_to_read)
last = max(lines)
for n, line in enumerate(file):
if n + 1 in lines:
yield line
if n + 1 > last:
return
>>> with open(r'c:\temp\words.txt') as f:
[s for s in read_specific_lines(f, [1, 2, 3, 1000])]
['A\n', 'a\n', 'aa\n', 'accordant\n']
นี่คือ 2 เซ็นต์เล็ก ๆ ของฉันสำหรับสิ่งที่คุ้มค่า;)
def indexLines(filename, lines=[2,4,6,8,10,12,3,5,7,1]):
fp = open(filename, "r")
src = fp.readlines()
data = [(index, line) for index, line in enumerate(src) if index in lines]
fp.close()
return data
# Usage below
filename = "C:\\Your\\Path\\And\\Filename.txt"
for line in indexLines(filename): # using default list, specify your own list of lines otherwise
print "Line: %s\nData: %s\n" % (line[0], line[1])
การเปลี่ยนแปลงที่ดีขึ้นเล็กน้อยสำหรับคำตอบของ Alok Singhal
fp = open("file")
for i, line in enumerate(fp,1):
if i == 26:
# 26th line
elif i == 30:
# 30th line
elif i > 30:
break
fp.close()
วัตถุไฟล์มีวิธีการ .readlines () ซึ่งจะให้รายชื่อของเนื้อหาของไฟล์หนึ่งบรรทัดต่อรายการรายการ หลังจากนั้นคุณสามารถใช้เทคนิคการแบ่งรายการแบบปกติได้
@OP คุณสามารถใช้แจกแจง
for n,line in enumerate(open("file")):
if n+1 in [26,30]: # or n in [25,29]
print line.rstrip()
file = '/path/to/file_to_be_read.txt'
with open(file) as f:
print f.readlines()[26]
print f.readlines()[30]
การใช้คำสั่ง with จะเป็นการเปิดไฟล์พิมพ์บรรทัดที่ 26 และ 30 จากนั้นปิดไฟล์ ! ง่าย
readlines()
ตัววนซ้ำจะหมดลงและการโทรครั้งที่สองจะส่งคืนรายการว่างเปล่าหรือโยนข้อผิดพลาด (จำไม่ได้ว่าใคร)
คุณสามารถทำสิ่งนี้ได้ง่าย ๆ ด้วยซินแท็กซ์นี้ที่มีคนพูดถึงไปแล้ว
inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])
หากต้องการพิมพ์บรรทัด # 3
line_number = 3
with open(filename,"r") as file:
current_line = 1
for line in file:
if current_line == line_number:
print(file.readline())
break
current_line += 1
ผู้แต่งต้นฉบับ: Frank Hofmann
หากต้องการพิมพ์บางบรรทัดในไฟล์ข้อความ สร้างรายการ "lines2print" จากนั้นเพียงพิมพ์เมื่อการแจงนับคือ "ใน" รายการ lines2print หากต้องการกำจัด '\ n' พิเศษให้ใช้ line.strip () หรือ line.strip ('\ n') ฉันชอบ "list comprehension" และพยายามใช้เมื่อฉันสามารถ ฉันชอบวิธีการ "กับ" ในการอ่านไฟล์ข้อความเพื่อป้องกันการเปิดไฟล์ไม่ว่าด้วยเหตุผลใด
lines2print = [26,30] # can be a big list and order doesn't matter.
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in lines2print]
หรือถ้ารายการมีขนาดเล็กเพียงพิมพ์ในรายการเป็นรายการลงในความเข้าใจ
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]
เพื่อพิมพ์บรรทัดที่ต้องการ หากต้องการพิมพ์บรรทัดด้านบน / ด้านล่างบรรทัดที่ต้องการ
def dline(file,no,add_sub=0):
tf=open(file)
for sno,line in enumerate(tf):
if sno==no-1+add_sub:
print(line)
tf.close()
ดำเนินการ ----> dline ("D: \ dummy.txt", 6) คือ dline ("พา ธ ไฟล์", line_number ถ้าคุณต้องการให้บรรทัดบนของบรรทัดการค้นหาให้ 1 สำหรับต่ำกว่า -1 นี่คือค่าเริ่มต้นที่ไม่จำเป็น จะต้องดำเนินการ 0)
หากคุณต้องการอ่านบรรทัดที่เฉพาะเจาะจงเช่นบรรทัดที่เริ่มต้นหลังจากบรรทัดเกณฑ์บางบรรทัดคุณสามารถใช้รหัสต่อไปนี้
file = open("files.txt","r")
lines = file.readlines() ## convert to list of lines
datas = lines[11:] ## raed the specific lines
f = open(filename, 'r')
totalLines = len(f.readlines())
f.close()
f = open(filename, 'r')
lineno = 1
while lineno < totalLines:
line = f.readline()
if lineno == 26:
doLine26Commmand(line)
elif lineno == 30:
doLine30Commmand(line)
lineno += 1
f.close()
ฉันคิดว่ามันจะใช้ได้
open_file1 = open("E:\\test.txt",'r')
read_it1 = open_file1.read()
myline1 = []
for line1 in read_it1.splitlines():
myline1.append(line1)
print myline1[0]