Как только читать строки в текстовом файле после определенной строки, используя Python?
Используя python, я хотел бы прочитать в словарь все строки в текстовом файле, которые идут после определенной строки. Я хотел бы сделать это более тысячи текстовых файлов.
Я могу идентифицировать и распечатать конкретную строку ('Abstract'), используя следующий код (полученный из этого ответа переполнения стека):
for files in filepath:
with open(files, 'r') as f:
for line in f:
if 'Abstract' in line:
print line;
Но как мне сказать python начать читать строки, которые идут только после строки?
6 ответов
Просто начните другой цикл, когда достигнете строки, с которой хотите начать:
for files in filepath:
with open(files, 'r') as f:
for line in f:
if 'Abstract' in line:
for line in f: # now you are at the lines you want
# do work
Файловый объект - это его собственный итератор, поэтому, когда мы достигаем строки с абстрактным в нем, мы продолжаем нашу итерацию с этой строки, пока мы не используем итератор.
Простой пример:
gen = (n for n in xrange(8))
for x in gen:
if x == 3:
print("starting second loop")
for x in gen:
print("In second loop",x)
else:
print("In first loop", x)
In first loop 0
In first loop 1
In first loop 2
starting second loop
In second loop 4
In second loop 5
In second loop 6
In second loop 7
Вы также можете использовать itertools.dropwise, чтобы использовать строки до нужной вам точки.
from itertools import dropwhile
for files in filepath:
with open(files, 'r') as f:
dropped = dropwhile(lambda _line: "Abstract" not in _line, f)
next(dropped,"")
for line in dropped:
print(line)
Используйте логическое значение, чтобы игнорировать строки до этой точки:
found_abstract = False
for files in filepath:
with open(files, 'r') as f:
for line in f:
if 'Abstract' in line:
found_abstract = True
if found_abstract:
#do whatever you want
Для меня следующий код легче понять.
with open(file_name, 'r') as f:
while not 'Abstract' in next(f):
pass
for line in f:
#line will be now the next line after the one that contains 'Abstract'
Ты можешь использовать itertools.dropwhile
а также itertools.islice
здесь псевдо-пример:
from itertools import dropwhile, islice
for fname in filepaths:
with open(fname) as fin:
start_at = dropwhile(lambda L: 'Abstract' not in L.split(), fin)
for line in islice(start_at, 1, None): # ignore the line still with Abstract in
print line
Просто чтобы уточнить, ваш код уже "читает" все строки. Чтобы начать "обращать внимание" на строки после определенной точки, вы можете просто установить логический флаг, указывающий, следует ли игнорировать строки, и проверять его в каждой строке.
pay_attention = False
for line in f:
if pay_attention:
print line
else: # We haven't found our trigger yet; see if it's in this line
if 'Abstract' in line:
pay_attention = True
Если вы не возражаете против перестановки кода, вы также можете использовать вместо этого два частичных цикла: один цикл, который заканчивается, когда вы нашли свою триггерную фразу ('Abstract'
) и тот, который читает все следующие строки. Этот подход немного чище (и немного быстрее).
for skippable_line in f: # First skim over all lines until we find 'Abstract'.
if 'Abstract' in skippable_line:
break
for line in f: # The file's iterator starts up again right where we left it.
print line
Причина этого заключается в том, что объект файла возвращается open
ведет себя как генератор, а не, скажем, как список: он генерирует значения только по запросу. Поэтому, когда первый цикл останавливается, файл остается с его внутренней позицией, установленной в начале первой "непрочитанной" строки. Это означает, что когда вы входите во второй цикл, первая строка, которую вы видите, является первой строкой после той, которая вызвала break
,
Делая предположение о том, как словарь вовлечен, я написал бы это следующим образом:
lines = dict()
for filename in filepath:
with open(filename, 'r') as f:
for line in f:
if 'Abstract' in line:
break
lines[filename] = tuple(f)
Таким образом, для каждого файла ваш словарь содержит набор строк.
Это работает, потому что цикл читает до включенной вами строки, включая оставшиеся строки в файле, готовые для чтения из f
,