Итерация файла, проверка существования строки - PullRequest
6 голосов
/ 08 февраля 2012

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

f = open("somefile.txt")

for line in f:
    do stuff

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

Ответы [ 4 ]

7 голосов
/ 08 февраля 2012

Если мое понимание верно, и вы хотите работать с каждой строкой по очереди, используя какое-то значение из следующей строки, я бы предложил просто сохранить значение, которое вы сейчас читаете, и работать с последним значением. Работа в обратном порядке - 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. Тот же эффект.

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

3 голосов
/ 08 февраля 2012

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

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

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

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

0 голосов
/ 08 февраля 2012
with open('somefile.txt') as f, open('somefile.txt') as g:
    g.readline()
    lines = ( (f.readline(),line) for line in g)
        for precline,aheadline in lines:
            # do what you want
0 голосов
/ 08 февраля 2012

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

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 '-------'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...