Nano Hash - криптовалюты, майнинг, программирование

Итерация файла, проверка наличия строки

Я читаю файл, используя цикл for, подобный этому...

f = open("somefile.txt")

for line in f:
    do stuff

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

07.02.2012

  • Или я могу как-то проверить, существует ли следующая строка, прежде чем пытаться ее прочитать? 08.02.2012
  • Что вы подразумеваете под «поместить в текущую строку»??? Вы хотите изменить записанную строку на жестком диске с данными, присутствующими в строке впереди ?? 08.02.2012

Ответы:


1

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

last_line = None

with open("somefile.txt") as f:
    for line in f:
        if not last_line == None:
            do_stuff(last_line, extract_needed_part(line))
        last_line = line
do_stuff(last_line) #The final line without anything following it.

С математической точки зрения, вместо строки n и строки n+1 сделайте строку n-1 и строку n. Тот же эффект.

Преимущество этого метода в том, что он не означает загрузку всего файла в начале.

07.02.2012
  • Я хотел бы проголосовать за ваш ответ, но, к сожалению, у меня пока нет 15 репутации, ха. Спасибо, хотя, я нашел это полезным. 08.02.2012
  • @ user1178682 Вы можете принять мой ответ, если он решил вашу проблему: meta.stackexchange.com/questions/5234/ 09.02.2012

  • 2

    Если ваш файл невелик, вы можете прочитать его в память и использовать там:

    f = open("somefile.txt")
    lines = f.readlines()
    f.close()
    
    for index, value in enumerate(lines):
        # Check if next line exists
        if index + 1 > len(lines):
            next_line = lines(index + 1)
            # do something with line and next_line
    

    Изменить:

    Для больших файлов было бы проще просто запомнить предыдущую строку:

    f = open("somefile.txt")
    previous_line = f.readline()
    for line in f:
        # Do something with line and previous_line
        print(line, previous_line)
        # Save this line for the next iteration
        previous_line = line
    

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

    Например, этот код ничего не сделает, если в вашем файле всего одна строка.

    07.02.2012
  • Проблема в том, что файлы довольно большие, я хочу сделать обработку без необходимости хранить каждую строку в памяти изначально. Я надеялся, что будет какой-то метод, о котором я не знаю. Это хороший вариант резервного копирования, если ничего не помогает. Спасибо за ответ. 08.02.2012
  • В вашем примере для вашего редактирования, которое в значительной степени повторяет мой ответ, за исключением того, что вы не используете with (что вы должны) и для первого выполнения, previous_line и строка будут одинаковыми. 08.02.2012
  • У меня есть предложение try, IOException в моем реальном коде вместо with (для совместимости). Это скорее обобщение, когда мы можем предположить, что файл существует и не вернет ошибку. Тем не менее, консенсус, похоже, заключается в том, чтобы просто придерживаться предыдущей строки. Если это лучший способ, я буду использовать его. 08.02.2012
  • Привет Lattyware, Строка for в конструкции f НЕ сбрасывает указатель файла f, поэтому первой строке значения присваивается ВТОРАЯ строка файла. Попробуйте. 09.02.2012
  • @secretmike Моя ошибка. Однако по-прежнему рекомендуется использовать with. 13.03.2012

  • 3

    Если ваш файл помещается в памяти, вы можете попробовать что-то вроде этого:

    f = open('somefile.txt')
    lines = f.read().splitlines()
    
    for current_line, next_line in zip(lines, lines[1:]):
        print current_line
        print next_line
        print '-------'
    

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

    Изменить: в качестве альтернативы для длинных файлов вы можете использовать библиотеку itertools следующим образом:

    import itertools
    f = open('somefile.txt')
    i1, i2 = itertools.tee(f)
    lines = itertools.izip(i1, itertools.islice(i2, 1, None))
    for current_line, next_line in lines:
        print current_line
        print next_line
        print '-------'
    

    В таком случае:

    • itertools.tee используется для создания двух независимых итераторов (один для текущей строки и один для следующей строки), которые используют исходный итератор файла.
    • itertools.slice используется для запуска итератора следующей строки во второй строке.
    • itertools.izip используется для объединения результатов обоих итераторов построчно в кортеж.

    Редактировать 2: как было предложено @eyquem, вы также можете открыть файл дважды:

    import itertools
    f = open('somefile.txt')
    g = open('somefile.txt')
    lines = itertools.izip(f, itertools.islice(g, 1, None))
    for current_line, next_line in lines:
        print current_line
        print next_line
        print '-------'
    
    07.02.2012
  • Нет необходимости использовать tee(). Просто определите другой обработчик файлов: g = open('somefile.txt') и переместите его на одну строку вперед с помощью g.readline() . Затем lines = ((f.readline(),line) for line in g) 08.02.2012
  • @eyquem Спасибо за ваш комментарий. Я отредактировал ответ, чтобы включить ваш комментарий. 08.02.2012
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..