如何在Python中一次读取N行文件?

mad*_*mer 30 python file-io iterator

我需要一次读取最多N行读取一个大文件,直到EOF.在Python中最有效的方法是什么?就像是:

with open(filename, 'r') as infile:
    while not EOF:
        lines = [get next N lines]
        process(lines)
Run Code Online (Sandbox Code Playgroud)

Mar*_*rau 34

一个解决方案是列表理解和切片运算符:

with open(filename, 'r') as infile:
    lines = [line for line in infile][:N]
Run Code Online (Sandbox Code Playgroud)

在此之后lines是行元组.但是,这会将整个文件加载到内存中.如果您不想这样(即文件可能非常大),还有另一种使用生成器表达式和isliceitertools包的解决方案:

from itertools import islice
with open(filename, 'r') as infile:
    lines_gen = islice(infile, N)
Run Code Online (Sandbox Code Playgroud)

lines_gen 是一个生成器对象,它为您提供文件的每一行,并可以在这样的循环中使用:

for line in lines_gen:
    print line
Run Code Online (Sandbox Code Playgroud)

这两种解决方案最多可以提供N行(如果文件没有那么多,则会更少).

  • 该解决方案没有回答"如何在EOF之前一次读取N行"的问题.它只能提供一次读取N行的机制,但之后只演示一次读取一行N行(结束时的for循环). (21认同)
  • OP 指出 **我需要通过一次最多读取 N 行来读取一个大文件**,而您的第一个解决方案将所有行加载到内存中?!也许您甚至不应该考虑第一个解决方案并将其从您的答案中删除! (6认同)
  • 简化为`lines = islice(infile,N)` (3认同)
  • 注意:它读取N行并停止.要读取接下来的N行,您可以将代码包装在循环中(直到EOF)或使用我的答案中显示的分组器配方. (2认同)

jfs*_*jfs 13

文件对象是Python中的行上的迭代器.要一次遍历文件N行,你可以使用grouper()itertools的配方(参见什么是最"pythonic"方式迭代块中的列表?):

#!/usr/bin/env python2

from itertools import izip_longest

def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return izip_longest(*args, fillvalue=fillvalue)
Run Code Online (Sandbox Code Playgroud)

with open(filename) as f:
     for lines in grouper(f, N, ''):
         assert len(lines) == N
         # process N lines here
Run Code Online (Sandbox Code Playgroud)

  • 我不介意编辑。评论是为了你的利益。[`itertools.zip_longest()`](https://github.com/python/cpython/blob/2686f50b3bfd921dfc4f6eb0b663be56a73357ae/Modules/itertoolsmodule.c#L4272) 在 Python 3 和 [`zip_longest()itertools. //github.com/python/cpython/blob/c8f718080e60aa93842e20ee95dd90b29cb570b9/Modules/itertoolsmodule.c#L3828) 在Python 2中是同一个对象。 (3认同)
  • @Kevin J. Chase:1-二进制文件是`b'\n'`行上的迭代器 2-`itertools.izip_longest` 在 Python 3 中没有被删除,它被重命名为 `itertools.zip_longest` (2认同)

Ana*_*lij 9

此代码适用于文件和任何行中的任何行数N.如果你有1100 lines文件N = 200,你会得到5次处理200行的块和100行的一次.

with open(filename, 'r') as infile:
    lines = []
    for line in infile:
        lines.append(line)
        if len(lines) >= N:
            process(lines)
            lines = []
    if len(lines) > 0:
        process(lines)
Run Code Online (Sandbox Code Playgroud)