2016-09-17 117 views
0

我想知道是否有一种方法可以批量读取文件中的多行文本。例如:从批处理文件中批量读取多行

with open(filename, 'rb') as f: 
    for n_lines in f: 
     process(n_lines) 

在这个函数中,我会做的是:每次迭代,下n行会从文件,逐批阅读。

因为一个文件太大。我想要做的是逐个阅读它。

+0

你可以阅读所有具有'readlines'的行,然后将连续的十行片传递给'process'。 –

+0

否。因为文件太大。我想要做的是逐批阅读。 – fluency03

+0

尝试'f.read(byte_size)'其中byte_size是要读取的字节字符数,如果这就是你想要的。 –

回答

3

itertools.islice和两个ARG iter可用来做到这一点,但它是一个有点滑稽:

from itertools import islice 

n = 5 # Or whatever chunk size you want 
with open(filename, 'rb') as f: 
    for n_lines in iter(lambda: tuple(islice(f, n)),()): 
     process(n_lines) 

这将让islice在荷兰国际集团关闭n线一段时间(使用tuple实际强制读入整个块)直到f耗尽,此时它将停止。如果文件中的行数不是n的偶数倍,则最后的块将小于n行。如果你希望所有的线是一个字符串,改变for循环是:

# The b prefixes are ignored on 2.7, and necessary on 3.x since you opened 
    # the file in binary mode 
    for n_lines in iter(lambda: b''.join(islice(f, n)), b''): 

另一种方法是使用izip_longest为目的,避免了lambda功能:

from future_builtins import map # Only on Py2 
from itertools import izip_longest # zip_longest on Py3 

    # gets tuples possibly padded with empty strings at end of file 
    for n_lines in izip_longest(*[f]*n, fillvalue=b''): 

    # Or to combine into a single string: 
    for n_lines in map(b''.join, izip_longest(*[f]*n, fillvalue=b'')): 
+0

我想知道,在使用'islice'的解决方案中,是一次读取的n行,或者实际上一个一个地读取并分组在一起n行块? – fluency03

+0

@ChangLiu:在所有情况下,它们都是逐个读取的,但是发生了块缓冲,所以几率只有0-2个读取所需的任何给定的块。没有什么不可思议的方式来读取'n'行作为一个单一的读取;哎呀,在较低的层次上,没有办法将_one_行读作单个读取,它可以是缓冲(快速,但是超读),也可以一次拉出一个字符(没有重读,但速度更慢)。 – ShadowRanger

0

实际上,你可以只遍历行的文件(见file.next文档 - 这也适用于Python 3中),如

with open(filename) as f: 
    for line in f: 
     something(line) 

使你的代码可以被改写为

n=5 # your chunk size 
with open(filename) as f: 
    batch=[] 
    for line in f: 
     chunk.append(line) 
     if len(batch)==n: 
      process(batch) 
      chunk=[] 
process(batch) #this batch might be smaller or even empty 

但一般只是逐行处理更方便(第一个例子)

如果你不关心每批有多少行准确读取,而只是它不是Ø多的内存,然后使用file.readlinessizehint

size_hint=2<<24 # 16MB 
with open(filename) as f: 
    while f: # not sure if this check works 
     process(f.readlines(size_hint) 
+0

这样,你实际上每次都在读一行,我想要的是每次读n行。 – fluency03

+0

当您逐行读取文件时,没有函数直接读取n行 - 实际上是因为缓冲(缓冲区大小可以作为arg传递给'open),通常只有一个读取多行的磁盘。 – janbrohl

+0

扩展我的答案,其中包括'readlines'实际上是多行读取 – janbrohl