Чтение определенного количества строк в python

#python #data-mining #large-data

#python #интеллектуальный анализ данных #большие данные

Вопрос:

Например, у меня есть текстовый файл с БОЛЬШИМИ данными:

 #01textline1
1 2 3 4 5 6
2 3 5 6 7 3
3 5 6 7 6 4
4 6 7 8 9 9

1 2 3 6 4 7
3 5 7 7 8 4
4 6 6 7 8 5

3 4 5 6 7 8
4 6 7 8 8 9
..
..
  

Комментарии:

1. Отступ выглядит неправильно

2. вы читали это? docs.python.org/2/library/linecache.html

3. В дополнение к проблеме с отступом, вы открываете file2 с флагом «r». Строка == «#03textline3» не прерывается, потому что есть символ новой строки (n), который вызывает сбой вашего условного обозначения. Вы могли бы сделать это, если «#03textline3» в строке.

Ответ №1:

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

Обратите внимание, что я изменил ваше file.readlines() значение на strip завершающие строки.

(Использование file.read().splitlines() может завершиться неудачей, если read() заканчивается в середине строки данных.)

 file1 = open("data.txt","r")
file2=open("newdata.txt","w")
lines = [ line.rstrip() for line in file1.readlines() ]

firstIndex = lines.index("#02textline2")
secondIndex = lines.index("#03textline3")

print firstIndex, secondIndex
file2.write("n".join(lines[firstIndex    1 : secondIndex]))


file1.close()
file2.close()
  

Комментарии:

1. На самом деле нет необходимости загружать и обрабатывать весь файл

2. @wnnmaw, это очень справедливое замечание, но оригинальное решение OP уже считало весь файл в память, поэтому я старался держаться как можно ближе к нему, одновременно делая логику максимально чистой.

3. @wnnmaw, основное предположение заключается в том, что файл достаточно мал, что стоимость его чтения в память недостаточно высока, чтобы оператору было все равно.

Ответ №2:

В конце каждой строки есть символ возврата строки, так что это:

 if line == "#03textline3":
  

никогда не будет истинным, поскольку строка на самом деле "#03textline3n" . Почему вы не использовали тот же синтаксис, что и тот, который вы использовали для "#02textline2" ? Это сработало бы:

 if "#03textline3" in line: # Or ' line == "#03textline3n" '
    break;
  

Кроме того, вы должны исправить отступ для always_print = True строки.

Ответ №3:

Вот что я бы посоветовал сделать:

 firstKey = "#02textline2"
secondKey = "#03textline3"

with open("data.txt","r") as fread:
    for line in fread:
        if line.rstrip() == firstKey:
            break

    with open("newdata.txt","w") as fwrite:
        for line in fread:
            if line.rstrip() == secondKey:
                break
            else:
                fwrite.write(line)
  

Этот подход использует тот факт, что Python обрабатывает файлы как итераторы. Первые for циклы повторяются через итератор файлов f , пока не будет найден первый ключ. Цикл прерывается, но итератор остается в текущей позиции. Когда он возвращается обратно, вторые циклы начинаются там, где заканчиваются первые. Затем мы напрямую записываем нужные строки в новый файл, а остальные отбрасываем

Преимущества:

  • Это не загружает весь файл в память, сохраняются только строки между firstKey и secondKey , и только строки перед secondKey тем, как когда-либо считываются сценарием

  • Ни одна запись не просматривается и не обрабатывается более одного раза

  • Диспетчер контекста with — более безопасный способ использования файлов