Reading specific lines only
我使用for循环来读取文件,但我只想读取特定的行,比如第26行和第30行。是否有任何内置功能来实现这一点?
谢谢
如果要读取的文件很大,并且您不想同时读取内存中的整个文件:
1 2 3 4 5 6 7 8 9 | 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() |
注意,
在python 2.6或更高版本中:
1 2 3 4 5 6 7 8 | 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 |
。
快速回答:
1 2 3 4 | f=open('filename') lines=f.readlines() print lines[25] print lines[29] |
号
或:
1 2 3 4 5 6 7 | lines=[25, 29] i=0 f=open('filename') for line in f: if i in lines: print i i+=1 |
对于提取多行有一个更优雅的解决方案:linecache(由"python:How to jump to a specific line in a great text file?"提供)。上一个stackoverflow.com问题)。
引用上面链接的python文档:
1 2 3 4 | >>> import linecache >>> linecache.getline('/etc/passwd', 4) 'sys:x:3:3:sys:/dev:/bin/sh ' |
。
把
如果文件可能非常大,并且在读取内存时会导致问题,那么最好接受@alok的建议并使用enumerate()。
总结如下:
- 使用
fileobject.readlines() 或for line in fileobject 作为小文件的快速解决方案。 - 使用
linecache 获得更优雅的解决方案,这对于读取多个文件来说速度相当快,可以反复使用。 - 接受@alok的建议,并使用
enumerate() 处理可能非常大且无法放入内存的文件。请注意,使用此方法可能会变慢,因为文件是按顺序读取的。
快速而紧凑的方法可以是:
1 2 | def picklines(thefile, whatlines): return [x for i, x in enumerate(thefile) if i in whatlines] |
它接受任何打开的文件,如对象
1 2 | def yieldlines(thefile, whatlines): return (x for i, x in enumerate(thefile) if i in whatlines) |
。
这基本上只适用于循环——注意,唯一的区别在于在
还要注意的是,尽管提到了"行"和"文件",这些函数还是非常通用的——它们可以处理任何不可重复的项目,无论是打开的文件还是其他任何文件,根据项目的渐进编号返回项目列表(或生成器)。所以,我建议使用更合适的通用名称;-)。
为了提供另一种解决方案:
1 2 | import linecache linecache.getline('Sample.txt', Number_of_Line) |
号
我希望这是快速和容易的:)
如果你想要第7行
1 | line = open("file.txt","r").readlines()[7] |
号
读取文件的速度非常快。读取一个100MB文件需要不到0.1秒的时间(请参阅我的文章用Python读写文件)。因此,您应该完整地阅读它,然后使用单行。
这里大多数的答案都不是错的,而是不好的风格。打开文件应该总是用
所以你应该这样做:
1 2 3 4 | 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 |
。大文件
如果您碰巧有一个巨大的文件,并且内存消耗是一个问题,那么您可以一行一行地处理它:
1 2 3 | with open("path/to/file.txt") as f: for i, line in enumerate(f): pass # process line i |
为了完整起见,这里还有一个选择。
让我们从python文档的定义开始:
slice An object usually containing a portion of a sequence. A slice is created using the subscript notation, [] with colons between numbers when several are given, such as in variable_name[1:3:5]. The bracket (subscript) notation uses slice objects internally (or in older versions, __getslice__() and __setslice__()).
号
虽然slice表示法一般不直接适用于迭代器,但是
1 2 3 4 5 6 7 8 9 10 11 | 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 |
该函数的另一个优点是,它直到结束时才读取迭代器。所以你可以做更复杂的事情:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
号
回答最初的问题:
1 2 3 | # how to read lines #26 and #30 In [365]: list(islice(xrange(1,100), 25, 30, 4)) Out[365]: [26, 30] |
其中一些很可爱,但可以做得更简单:
1 2 3 4 5 6 7 8 | 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+数据文件上工作。祝你好运!
可以执行seek()调用,将读取头定位到文件中的指定字节。除非您确切知道要读取的行之前文件中写入了多少字节(字符),否则这对您没有帮助。也许您的文件是严格格式化的(每行是x字节数?)或者,如果你真的想提高速度,你可以自己计算字符数(记住要包括不可见的字符,如换行符)。
否则,您必须按照这里已经提出的许多解决方案之一,在您想要的行之前阅读每一行。
我更喜欢这种方法,因为它更通用,也就是说,您可以在文件中、在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 ', 'a ', 'aa ', 'accordant '] |
。
阿洛克·辛哈尔的回答的一个更好和微小的改变
1 2 3 4 5 6 7 8 9 | 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() |
这个怎么样:
1 2 3 4 5 | >>> 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将完全满足您的需要(这是您可以读取当前行的行号)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 ', 'Abernathy '] # note that index 25 is the 26th item |
。
这是我的2美分,值多少钱;)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 Data: %s " % (line[0], line[1]) |
号
如果您的大文本文件
1 2 3 4 | with open(file) as f: f.seek(n*l) line = f.readline() # please notice the s at the end! last_pos = f.tell() |
号
免责声明:这只适用于相同长度的文件!
打印第3行,
1 2 3 4 5 6 7 8 9 | 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 |
号
原作者:弗兰克·霍夫曼
@你可以用枚举
1 2 3 | for n,line in enumerate(open("file")): if n+1 in [26,30]: # or n in [25,29] print line.rstrip() |
号
您可以使用前面提到的语法非常简单地做到这一点,但这是迄今为止最简单的方法:
1 2 3 4 | inputFile = open("lineNumbers.txt","r") lines = inputFile.readlines() print (lines[0]) print (lines[2]) |
。
文件对象有一个.readlines()方法,它将为您提供文件内容的列表,每个列表项一行。之后,您可以使用普通的列表切片技术。
http://docs.python.org/library/stdtypes.html_file.readlines
1 2 3 4 | file = '/path/to/file_to_be_read.txt' with open(file) as f: print f.readlines()[26] print f.readlines()[30] |
。
使用WITH语句,将打开文件,打印第26行和第30行,然后关闭文件。简单!
很快就到了。
在文本文件中打印某些行。创建"lines2print"列表,然后仅当枚举"在"行2打印列表中时打印。若要清除多余的'',请使用line.strip()或line.strip('')。我只是喜欢"列表理解",并尽可能地使用。我喜欢用"with"方法读取文本文件以防止以任何理由打开文件。
1 2 3 4 | 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] |
号
或者如果列表很小,只需将列表作为列表键入理解。
1 2 | with open("filepath", 'r') as fp: [print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]] |
号
打印所需行。在所需行的上方/下方打印行。
1 2 3 4 5 6 | 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() |
。
执行---->d line("d:dummy.txt",6),即dline("文件路径",行号,如果希望搜索行的上行给出1表示下行-1,这是可选的默认值,将取0)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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() |
我想这行
1 2 3 4 5 6 | 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] |
。