我需要通过一次读取最多N行读取一个大文件,直到EOF。在Python中最有效的方法是什么?类似的东西:
with open(filename, 'r') as infile:
while not EOF:
lines = [get next N lines]
process(lines)
答案 0 :(得分:30)
一个解决方案是列表推导和切片运算符:
with open(filename, 'r') as infile:
lines = [line for line in infile][:N]
此后lines
是行元组。但是,这会将整个文件加载到内存中。如果你不想要这个(即文件可能真的很大),还有另一个使用生成器表达式和itertools包中的islice
的解决方案:
from itertools import islice
with open(filename, 'r') as infile:
lines_gen = islice(infile, N)
lines_gen
是一个生成器对象,它为您提供文件的每一行,并且可以在这样的循环中使用:
for line in lines_gen:
print line
这两种解决方案最多可以提供N行(如果文件没有这么多,则为更少)。
答案 1 :(得分:11)
文件对象是Python中的行上的迭代器。要一次迭代文件N行,您可以使用grouper() itertools' recipe(请参阅What is the most “pythonic” way to iterate over a list in chunks?):
#!/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)
with open(filename) as f:
for lines in grouper(f, N, ''):
assert len(lines) == N
# process N lines here
答案 2 :(得分: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)
答案 3 :(得分:1)
也许:
for x in range(N):
lines.append(f.readline())
答案 4 :(得分:1)
我认为您应该使用块而不是指定要读取的行数。它使您的代码更加健壮和通用。即使行很大,使用chunk也只会将分配的数据量上传到内存中。
请参阅this链接
答案 5 :(得分:0)
您可能需要做一些简单的事情:
lines = [infile.readline() for _ in range(N)]
评论后更新:
lines = [line for line in [infile.readline() for _ in range(N)] if len(line) ]
答案 6 :(得分:0)
如果您可以提前阅读完整档案;
infile = open(filename, 'r').readlines()
my_block = [line.strip() for line in infile[:N]]
cur_pos = 0
while my_block:
print (my_block)
cur_pos +=1
my_block = [line.strip() for line in infile[cur_pos*N:(cur_pos +1)*N]]
答案 7 :(得分:0)
我需要一次从文件中读取n行以读取超大文件(〜1TB),并写了simple package来做到这一点。如果您pip install bigread
,则可以执行以下操作:
from bigread import Reader
stream = Reader(file='large.txt', block_size=10)
for i in stream:
print(i)
block_size
是一次读取的行数。
答案 8 :(得分:0)
我一直在寻找同一个问题的答案,但是之前并没有真正喜欢任何提议的东西,所以我最终写了这个有点丑陋的东西,完全可以实现我想要的,而无需使用奇怪的库。
def test(filename, N):
with open(filename, 'r') as infile:
lines = []
for line in infile:
line = line.strip()
if len(lines) < N-1:
lines.append(line)
else:
lines.append(line)
res = lines
lines = []
yield res
else:
if len(lines) != 0:
yield lines
答案 9 :(得分:-1)
for循环怎么样?
with open(filename, 'r') as infile:
while not EOF:
lines = []
for i in range(next N lines):
lines.append(infile.readline())
process(lines)