Как прочитать файл N строк одновременно в Python? - PullRequest
27 голосов
/ 29 апреля 2011

Мне нужно прочитать большой файл, читая не более N строк за раз, до EOF. Какой самый эффективный способ сделать это в Python? Что-то вроде:

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

Ответы [ 10 ]

33 голосов
/ 29 апреля 2011

Одним из решений было бы понимание списка и оператор среза:

with open(filename, 'r') as infile:
    lines = [line for line in infile][:N]

После этого lines - это кортеж строк.Однако это загрузит весь файл в память.Если вы не хотите этого (т.е. если файл может быть очень большим), есть другое решение, использующее выражение генератора и islice из пакета itertools:

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 строк (или меньше, если файл нене так много).

11 голосов
/ 01 мая 2011

Файловый объект - это итератор над строками в Python.Чтобы перебирать файл N строк одновременно, вы можете использовать grouper () itertools 'recipe (см. Какой самый «питонный» способ перебирать список в чанках?):

#!/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
9 голосов
/ 29 апреля 2011

Этот код будет работать с любым количеством строк в файле и любым 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)
1 голос
/ 29 апреля 2011

Я думаю, что вы должны использовать чанки вместо указания количества строк для чтения. Это делает ваш код более надежным и универсальным. Даже если строки большие, использование chunk загрузит в память только назначенное количество данных.

См. эту ссылку

1 голос
/ 29 апреля 2011

возможно:

for x in range(N):
  lines.append(f.readline())
0 голосов
/ 21 августа 2018

Я искал ответ на тот же вопрос, но мне не очень понравился какой-либо предложенный материал ранее, поэтому я закончил тем, что написал эту немного некрасивую вещь, которая делает именно то, что я хотел без использования странных библиотек .

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
0 голосов
/ 28 июня 2018

Мне нужно было читать по n строк за раз из файлов для очень больших файлов (~ 1 ТБ) и для этого написал простой пакет .Если вы pip install bigread, вы можете сделать:

from bigread import Reader

stream = Reader(file='large.txt', block_size=10) 
for i in stream:
  print(i)

block_size - это количество строк для чтения за раз.

0 голосов
/ 02 ноября 2017

Если вы можете прочитать полный файл заранее;

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]]
0 голосов
/ 29 апреля 2011

Возможно, вам придется сделать что-то простое:

lines = [infile.readline() for _ in range(N)]

Обновление после комментариев:

lines = [line for line in [infile.readline() for _ in range(N)] if len(line) ]
0 голосов
/ 29 апреля 2011

Как насчет цикла for?

with open(filename, 'r') as infile:
    while not EOF:
        lines = []
        for i in range(next N lines):
            lines.append(infile.readline())
        process(lines)
...