Câu trả lời:
Nếu tệp cần đọc lớn và bạn không muốn đọc toàn bộ tệp trong bộ nhớ cùng một lúc:
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()
Lưu ý rằng i == n-1
đối với n
dòng thứ.
Trong Python 2.6 trở lên:
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)
sử dụng x.next
, vì vậy nó không cần toàn bộ tập tin trong bộ nhớ.
big file
. Vòng lặp sẽ mất nhiều năm để đạt được chỉ số
Câu trả lời nhanh:
f=open('filename')
lines=f.readlines()
print lines[25]
print lines[29]
hoặc là:
lines=[25, 29]
i=0
f=open('filename')
for line in f:
if i in lines:
print i
i+=1
Có một giải pháp tinh tế hơn để trích xuất nhiều dòng: linecache (phép lịch sự của "python: làm thế nào để chuyển đến một dòng cụ thể trong một tệp văn bản lớn?" , Một câu hỏi stackoverflow.com trước đó).
Trích dẫn tài liệu python được liên kết ở trên:
>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'
Thay đổi 4
số dòng mong muốn của bạn và bạn đang bật. Lưu ý rằng 4 sẽ mang lại dòng thứ năm vì số đếm là không dựa trên.
Nếu tệp có thể rất lớn và gây ra sự cố khi đọc vào bộ nhớ, có thể nên lấy lời khuyên của @ Alok và sử dụng phép liệt kê () .
Để kết luận:
fileobject.readlines()
hoặc for line in fileobject
như một giải pháp nhanh chóng cho các tập tin nhỏ.linecache
cho một giải pháp thanh lịch hơn, sẽ khá nhanh để đọc nhiều tệp, có thể lặp đi lặp lại.enumerate()
cho các tệp có thể rất lớn và sẽ không vừa với bộ nhớ. Lưu ý rằng sử dụng phương pháp này có thể chậm vì tệp được đọc tuần tự.linecache
mô-đun, và có vẻ như nó đọc toàn bộ tập tin trong bộ nhớ. Vì vậy, nếu truy cập ngẫu nhiên quan trọng hơn tối ưu hóa kích thước, linecache
là phương pháp tốt nhất.
linecache
bây giờ dường như chỉ hoạt động cho các tệp nguồn python
linecache.getlines('/etc/passwd')[0:4]
để đọc trong dòng đầu tiên, thứ hai, thứ ba và thứ tư.
Một cách tiếp cận nhanh và gọn có thể là:
def picklines(thefile, whatlines):
return [x for i, x in enumerate(thefile) if i in whatlines]
điều này chấp nhận mọi đối tượng giống như tệp đang mở thefile
(tùy thuộc vào người gọi cho dù nó có được mở từ tệp đĩa hay thông qua ổ cắm, hoặc luồng giống như tệp khác) và một bộ chỉ mục dòng dựa trên không whatlines
và trả về danh sách, với dấu chân bộ nhớ thấp và tốc độ hợp lý. Nếu số lượng dòng được trả về là rất lớn, bạn có thể thích một trình tạo:
def yieldlines(thefile, whatlines):
return (x for i, x in enumerate(thefile) if i in whatlines)
về cơ bản chỉ tốt cho việc lặp lại - lưu ý rằng sự khác biệt duy nhất đến từ việc sử dụng dấu ngoặc tròn thay vì dấu ngoặc vuông trong return
câu lệnh, tạo ra sự hiểu biết danh sách và biểu thức trình tạo tương ứng.
Lưu ý thêm rằng mặc dù đề cập đến "dây chuyền" và "tập tin" các chức năng này là nhiều, nhiều hơn nói chung - họ sẽ làm việc trên bất kỳ iterable, có thể là một tập tin mở hoặc bất kỳ khác, trả lại một danh sách (hoặc máy phát điện) các mặt hàng dựa trên số mục tiến bộ của họ. Vì vậy, tôi khuyên bạn nên sử dụng tên chung phù hợp hơn ;-).
whatlines
nên là một set
, bởi vì if i in whatlines
sẽ thực thi nhanh hơn với một tập hợp chứ không phải là một danh sách (được sắp xếp). Tôi đã không chú ý đến nó trước và thay vào đó đã nghĩ ra giải pháp xấu xí của riêng mình với danh sách được sắp xếp (nơi tôi không phải quét danh sách mỗi lần, trong khi if i in whatlines
đó), nhưng sự khác biệt về hiệu suất là không đáng kể (với dữ liệu của tôi) và điều này Giải pháp thanh lịch hơn nhiều.
Vì mục đích đưa ra một giải pháp khác:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
Tôi hy vọng điều này là nhanh chóng và dễ dàng :)
nếu bạn muốn dòng 7
line = open ("file.txt", "r"). readlines () [7]
close()
tập tin khi mở nó theo cách này?
Để hoàn thiện, đây là một lựa chọn nữa.
Hãy bắt đầu với một định nghĩa từ các tài liệu python :
lát Một đối tượng thường chứa một phần của chuỗi. Một lát cắt được tạo bằng cách sử dụng ký hiệu đăng ký, [] với dấu hai chấm giữa các số khi một số được đưa ra, chẳng hạn như trong biến_name [1: 3: 5]. Ký hiệu ngoặc (đăng ký) sử dụng các đối tượng lát bên trong (hoặc trong các phiên bản cũ hơn, __getslice __ () và __setslice __ ()).
Mặc dù ký hiệu lát cắt không thể áp dụng trực tiếp cho các trình vòng lặp nói chung, itertools
gói chứa hàm thay thế:
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
Ưu điểm bổ sung của hàm là nó không đọc iterator cho đến khi kết thúc. Vì vậy, bạn có thể làm những điều phức tạp hơn:
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
Và để trả lời câu hỏi ban đầu:
# how to read lines #26 and #30
In [365]: list(islice(xrange(1,100), 25, 30, 4))
Out[365]: [26, 30]
Đọc các tập tin là nhanh chóng đáng kinh ngạc. Đọc một tệp 100 MB chỉ mất chưa đến 0,1 giây (xem bài viết của tôi Đọc và ghi tệp bằng Python ). Do đó bạn nên đọc nó hoàn toàn và sau đó làm việc với các dòng đơn.
Những gì hầu hết câu trả lời ở đây làm không phải là sai, nhưng phong cách xấu. Mở tập tin phải luôn luôn được thực hiện vớiwith
vì nó đảm bảo rằng tệp được đóng lại.
Vì vậy, bạn nên làm điều đó như thế này:
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
Nếu bạn có một tập tin lớn và tiêu thụ bộ nhớ là một mối quan tâm, bạn có thể xử lý từng dòng một:
with open("path/to/file.txt") as f:
for i, line in enumerate(f):
pass # process line i
Một số trong số này là đáng yêu, nhưng nó có thể được thực hiện đơn giản hơn nhiều:
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)
Điều đó sẽ sử dụng danh sách cắt đơn giản, nó tải toàn bộ tệp, nhưng hầu hết các hệ thống sẽ giảm thiểu việc sử dụng bộ nhớ một cách phù hợp, nó nhanh hơn hầu hết các phương pháp được đưa ra ở trên và hoạt động trên các tệp dữ liệu 10G + của tôi. Chúc may mắn!
Bạn có thể thực hiện lệnh gọi () tìm vị trí đầu đọc của bạn đến một byte được chỉ định trong tệp. Điều này sẽ không giúp bạn trừ khi bạn biết chính xác có bao nhiêu byte (ký tự) được ghi trong tệp trước dòng bạn muốn đọc. Có lẽ tệp của bạn được định dạng nghiêm ngặt (mỗi dòng là X số byte?) Hoặc, bạn có thể tự đếm số lượng ký tự (nhớ bao gồm các ký tự vô hình như ngắt dòng) nếu bạn thực sự muốn tăng tốc độ.
Mặt khác, bạn phải đọc mọi dòng trước dòng bạn mong muốn, theo một trong nhiều giải pháp đã được đề xuất ở đây.
Nếu tệp văn bản lớn của bạn file
có cấu trúc chặt chẽ (có nghĩa là mọi dòng có cùng độ dài l
), bạn có thể sử dụng cho n
dòng -th
with open(file) as f:
f.seek(n*l)
line = f.readline()
last_pos = f.tell()
Tuyên bố từ chối Điều này chỉ hoạt động đối với các tệp có cùng độ dài!
Còn cái này thì sao:
>>> 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
Tôi thích cách tiếp cận này vì nó có mục đích chung hơn, tức là bạn có thể sử dụng nó trên một tệp, trên kết quả của f.readlines()
, trên một StringIO
đối tượng, bất cứ điều gì:
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']
Đây là 2 xu nhỏ của tôi, với giá trị của nó;)
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])
Một thay đổi tốt hơn và nhỏ hơn cho câu trả lời của 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()
Các đối tượng tệp có một phương thức .readlines () sẽ cung cấp cho bạn một danh sách các nội dung của tệp, một dòng trên mỗi mục danh sách. Sau đó, bạn chỉ có thể sử dụng các kỹ thuật cắt danh sách bình thường.
http://docs.python.org/l Library / stdtypes.html # file.readlines
@OP, bạn có thể sử dụng liệt kê
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]
Sử dụng câu lệnh with, điều này sẽ mở tệp, in các dòng 26 và 30, sau đó đóng tệp. Đơn giản!
readlines()
iterator sẽ hết và cuộc gọi thứ hai sẽ trả về một danh sách trống hoặc đưa ra một lỗi (không thể nhớ đó)
Bạn có thể làm điều này rất đơn giản với cú pháp mà ai đó đã đề cập, nhưng đó là cách dễ nhất để làm điều đó:
inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])
Để in dòng # 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
Tác giả gốc: Frank Hofmann
Để in một số dòng nhất định trong một tập tin văn bản. Tạo một danh sách "lines2print" và sau đó chỉ in khi liệt kê là "trong" danh sách lines2print. Để loại bỏ thêm '\ n', hãy sử dụng line.strip () hoặc line.strip ('\ n'). Tôi chỉ thích "hiểu danh sách" và cố gắng sử dụng khi tôi có thể. Tôi thích phương pháp "với" để đọc tệp văn bản để tránh để mở tệp vì bất kỳ lý do gì.
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]
hoặc nếu danh sách nhỏ chỉ cần nhập danh sách dưới dạng danh sách vào phần hiểu.
with open("filepath", 'r') as fp:
[print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]
Để in dòng mong muốn. Để in dòng trên / dưới dòng yêu cầu.
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()
thực thi ----> dline ("D: \ dummy.txt", 6) tức là dline ("đường dẫn tệp", line_number, nếu bạn muốn dòng trên của dòng tìm kiếm cho 1 cho dưới -1 thì đây là giá trị mặc định tùy chọn sẽ được lấy 0)
Nếu bạn muốn đọc các dòng cụ thể, chẳng hạn như dòng bắt đầu sau một số dòng ngưỡng thì bạn có thể sử dụng các mã sau đây,
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()
Tôi nghĩ rằng nó sẽ làm việc
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]