Подтвердить что ты не робот

Есть ли способ прочитать 10000 строк из файла в python?

Я относительно новичок в python, много работал над C. Поскольку я видел так много новых функций в python, которые я не знаю, мне было интересно, есть ли функция, которая может запрашивать 10000 строк из файла в python.

Что-то вроде этого - то, что я ожидаю, если такая функция существует:

lines = get_10000_lines(file_pointer)

У python была встроенная функция или есть какой-нибудь модуль, который я могу загрузить для этого? Если нет, то как это сделать проще всего. Мне нужно проанализировать огромный файл, поэтому я хочу прочитать 10000 строк и анализировать за время, чтобы сохранить память.

Спасибо за помощь!

4b9b3361

Ответ 1

from itertools import islice

with open(filename) as f:
    first10000 = islice(f, 10000)

Это устанавливает first10000 в итерируемый объект, т.е. вы можете перебрать его с помощью

for x in first10000:
    do_something_with(x)

Если вам нужен список, сделайте list(islice(f, 10000)).

Если файл содержит менее 10 тыс. строк, он просто вернет все строки в файле без отступов (в отличие от решения на основе range). При чтении файла в кусках EOF сигнализируется, что в результатах есть < 10000 строк:

with open(filename) as f:
    while True:
        next10k = list(islice(f, 10000))  # need list to do len, 3 lines down
        for ln in next10k:
            process(ln)
        if len(next10k) < 10000:
            break

Ответ 2

f.readlines() возвращает список, содержащий все строки данных в файле. Если задан необязательный параметр sizehint, он читает, что много байтов из файла и достаточно больше для завершения строки, и возвращает строки из этого. Это часто используется для эффективного чтения большого файла по строкам, но без необходимости загрузки всего файла в память. Возвращаются только полные строки.

Из документов.

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

Ответ 3

Вам действительно интересно, сколько строк у вас за раз? Обычно имеет смысл просто перебирать файловый объект по строкам:

f = open('myfile.txt', 'r')
for line in f:
    print line

Документация python указывает, что это предпочтительный способ обработки файлов:

Альтернативный подход к чтению строк - это цикл над файловым объектом. Это память эффективная, быстрая и ведет к упрощению кода.

См. документы python для примеров.

Ответ 4

Просто откройте файл и скажите Python прочитать строку 10000 раз.

lines = None
with open('<filename>') as file:
    lines = (file.readline() for i in range(10000))

Ответ 5

Вы уверены, что файл слишком большой для памяти?

Так как вызов функции имеет служебные данные (т.е. вызов одной и той же функции 10000 раз медленный), а память дешевая, я бы предложил просто прочитать все строки сразу, а затем нарезать результирующий список. Это, безусловно, самый быстрый способ, если вы хотите обработать следующие 10000 позже - они будут готовы к вам сразу.

with open("filename") as f:
    lines = f.readlines()

indices = range(0, len(lines), 10000) + [len(lines)]
for start, stop in zip(indices, indices[1:]):
    do_stuff_with(lines[start:stop])

Конечно, если файл не помещается в свободную память, это не сработает. Если так, я бы пошел с ChipJust answer. Вы даже можете создать функцию поиска цели с помощью readlines sizehint, tell и seek, который будет "входить" на ровно 10000 строк, если это важно.

Ответ 6

f = open('myfile.txt', 'r')
while True:
    bytes_lines = f.readlines(10000) # read no more than 10000 bytes
    if not bytes_lines: break # stop looping if no lines read
    for line in bytes_lines:
        text = line.decode("knownencoding") # text will be a unicode object

Быстрее читать сразу большое количество текста, а затем обрабатывать его. Это читает фрагменты текстов, а затем разбивает их на строки для вас. Это экономит при чтении. Он также даст вам только полные строки, поэтому вам не нужно иметь дело с присоединением к строкам строк.

Проверите это, чтобы убедиться, что чтение из файла, уже на его конце, не вызывает исключения.

Ответ 7

Нет функции, которая работает так, как вы хотите. Вы можете написать один достаточно легко, но вам может быть не лучше. Например, если вы получаете список строк, как показывает множество решений, то вы должны анализировать каждую строку индивидуально:

def get_10000_lines(f):
    while True:
        chunk = list(itertools.islice(f, 10000))
        if not chunk:
            break
        yield chunk

Если вы это сделаете, вы можете просто прочитать файл по одной строке за раз и проанализировать каждую строку. Файловый ввод-вывод будет буферизован в любом случае:

for line in f:
    analyze_the_line(line)

если вы хотите, чтобы одна строка содержала 10 000 строк, вы будете читать каждую строку отдельно и объединять их:

for chunk in get_10000_lines(f):
    str_10k = "".join(chunk)
    analyze_a_bunch(str_10k)

Теперь вы выполняете большую работу по распределению и объединению строк, что может и не стоить.

Лучше всего было бы, если бы вы могли проанализировать частичные линии, тогда вы можете просто прочитать файл в кусках 1 Мб:

while True:
    chunk = f.read(1000000)
    if not chunk:
        break
    analyze_a_bunch(chunk)

Ответ 8

Рисунок из нескольких других решений, но добавив завихрение...

>>> with open('lines.txt', 'r') as lines:
...     chunks = iter(lambda: list(itertools.islice(lines, 7)), [])
...     for chunk in chunks:
...         print chunk
... 
['0\n', '1\n', '2\n', '3\n', '4\n', '5\n', '6\n']
['7\n', '8\n', '9\n', '10\n', '11\n', '12\n', '13\n']
['14\n', '15\n', '16\n', '17\n', '18\n', '19\n', '20\n']
['21\n', '22\n', '23\n', '24\n', '25\n', '26\n', '27\n']
['28\n', '29\n', '30\n', '31\n', '32\n', '33\n', '34\n']
['35\n', '36\n', '37\n', '38\n', '39\n', '40\n', '41\n']
['42\n', '43\n', '44\n', '45\n', '46\n', '47\n', '48\n']
['49\n', '50\n', '51\n', '52\n', '53\n', '54\n', '55\n']
['56\n', '57\n', '58\n', '59\n', '60\n', '61\n', '62\n']
['63\n', '64\n', '65\n', '66\n', '67\n', '68\n', '69\n']
['70\n', '71\n', '72\n', '73\n', '74\n', '75\n', '76\n']
['77\n', '78\n', '79\n', '80\n', '81\n', '82\n', '83\n']
['84\n', '85\n', '86\n', '87\n', '88\n', '89\n', '90\n']
['91\n', '92\n', '93\n', '94\n', '95\n', '96\n', '97\n']
['98\n', '99\n']

Но здесь я должен признать, что, как говорили другие, использование readlines с байтовой подсказкой немного быстрее, если вам не нужно ровно 10000 строк (или 10000 строк каждый раз). Тем не менее, я не верю, что это происходит потому, что оно меньше читает. В readlines docstring многократно повторяется "Вызов readline() и возвращает список строк, которые читаются так". Поэтому я думаю, что увеличение скорости - это сокращение небольшого количества накладных расходов итератора. Определения (с использованием кода Marcin):

def do_nothing_islice(filename, nlines):
    with open(filename, 'r') as lines:
        chunks = iter(lambda: list(itertools.islice(lines, nlines)), [])
        for chunk in chunks:
            chunk

def do_nothing_readlines(filename, nbytes):
    with open(filename, 'r') as lines:
        while True:
            bytes_lines = lines.readlines(nbytes)
            if not bytes_lines:
                break
            bytes_lines

Тесты:

>>> %timeit do_nothing_islice('lines.txt', 1000)
10 loops, best of 3: 63.6 ms per loop
>>> %timeit do_nothing_readlines('lines.txt', 7000) # 7-byte lines, ish
10 loops, best of 3: 56.8 ms per loop
>>> %timeit do_nothing_islice('lines.txt', 10000)
10 loops, best of 3: 58.4 ms per loop
>>> %timeit do_nothing_readlines('lines.txt', 70000) # 7-byte lines, ish
10 loops, best of 3: 50.7 ms per loop
>>> %timeit do_nothing_islice('lines.txt', 100000)
10 loops, best of 3: 76.1 ms per loop
>>> %timeit do_nothing_readlines('lines.txt', 700000) # 7-byte lines, ish
10 loops, best of 3: 70.1 ms per loop

В файле со средней длиной строки 7 (0 → 1000000 печатается по очереди), используя readlines с подсказкой размера быстрее. Но только немного. Заметьте также странное масштабирование - я не понимаю, что там происходит.