我使用for循环来读取文件,但我只想读取特定的行,比如第26行和第30行。是否有任何内置功能来实现这一点?


当前回答

这是我的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])

其他回答

不要使用阅读线!

我的解决方案是:


with open(filename) as f:
    specify = [26, 30]
    results = list(
        map(lambda line: line[1],
            filter(lambda line: line[0] in specify,
                   enumerate(f))
            )
    )

对6.5G文件进行如下测试:

import time

filename = 'a.txt'
start = time.time()
with open(filename, 'w') as f:
    for i in range(10_000_000):
        f.write(f'{str(i)*100}\n')       
end1 = time.time()

with open(filename) as f:
    specify = [26, 30]
    results = list(
        map(lambda line: line[1],
            filter(lambda line: line[0] in specify,
                   enumerate(f))
            )
    )
end2 = time.time()
print(f'write time: {end1-start}')
print(f'read time: {end2-end1}')
# write time: 14.38945460319519
# read time: 8.380386352539062

我更喜欢这种方法,因为它更通用,即你可以在文件上使用它,在f.r edlines()的结果上,在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']

读取文件非常快。读取一个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+数据文件。好运!

文件对象有一个.readlines()方法,它将为您提供文件内容的列表,每个列表项一行。在此之后,您可以使用普通的列表切片技术。

http://docs.python.org/library/stdtypes.html#file.readlines