Answers:
如果要读取的文件很大,并且您不想一次读取内存中的整个文件:
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
th行。
在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(由“ python:如何跳转到巨大的文本文件中的特定行?”,这是上一个stackoverflow.com问题)。
引用上面链接的python文档:
>>> 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
现在似乎仅适用于python源文件
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
语句中使用了舍入而不是正方形的括号,分别使列表理解和生成器表达式成为可能。
此外应注意,尽管“线”,并注明“文件”这些功能很多,很多更普遍的-他们会在工作的任何可迭代的,无论是打开的文件或任何其他的,返回的项目清单(或发电机)根据其渐进项编号。因此,我建议使用更适当的通用名称;-)。
whatlines
应该是set
,因为if i in whatlines
使用set列表而不是(sorted)列表会更快地执行。我没有先注意到它,而是设计了自己的带排序列表的丑陋解决方案(我不必每次都扫描列表,if i in whatlines
只是这样做了),但是性能差异可以忽略不计(根据我的数据),这解决方案要优雅得多。
为了提供另一个解决方案:
import linecache
linecache.getline('Sample.txt', Number_of_Line)
我希望这是方便快捷的:)
如果你要第7行
line = open(“ file.txt”,“ r”)。readlines()[7]
close()
,以这种方式打开文件时如何处理?
为了完整起见,这里还有一个选择。
让我们从python docs的定义开始:
切片通常包含一部分序列的对象。使用下标符号[]创建切片,当给出多个变量时(例如在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
这个怎么样:
>>> 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()
如果您不介意导入,那么fileinput会完全满足您的需要(这是您可以读取当前行的行号)
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])
文件对象具有.readlines()方法,该方法将为您提供文件内容的列表,每个列表项一行。在那之后,您可以只使用常规的列表切片技术。
要打印第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
原作者:弗兰克·霍夫曼
在文本文件中打印某些行。创建一个“ lines2print”列表,然后仅在枚举“ lines2print”列表中时打印。要摆脱多余的“ \ n”,请使用line.strip()或line.strip('\ n')。我只喜欢“列表理解”,并在可以的时候尝试使用。我喜欢使用“ with”方法读取文本文件,以防止由于任何原因使文件保持打开状态。
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]
或者,如果list很小,只需在列表中输入list作为理解即可。
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()
execute ----> dline(“ D:\ dummy.txt”,6),即dline(“ file path”,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()