У меня есть:

with open(self.corpus_file) as infile:
    for line in infile:

Как я могу определить, является ли line последней строкой в infile?

Это с Python 3.6, если это имеет значение.

3
Shamoon 30 Июн 2019 в 01:26

5 ответов

Лучший ответ

Файловые объекты, возвращаемые open, являются итераторами в Python, поэтому вы можете искать StopIteration при выполнении next для использования строк в цикле while:

with open(self.corpus_file) as f: 
    line = None 
    while True: 
        try: 
            line = next(f) 
        except StopIteration: 
            break 

Теперь line должен содержать последнюю строку.

3
heemayl 29 Июн 2019 в 22:29

Вот простой способ:

from itertools import tee

with open(self.corpus_file) as infile:
    infile, check = tee(infile)
    try:
        next(check)
    except StopIteration:
        # file is empty
    for line in infile:
        try:
            next(check)
        except StopIteration:
            # line is the last line

Другой, еще более простой способ, если вам не нужно оставаться в курсе:

with open(self.corpus_file) as infile:
    for line in infile:
        pass

# line is now the last line
4
Rick supports Monica 29 Июн 2019 в 23:16

Используя тот факт, что файлы являются итераторами, вы можете использовать следующий общий рецепт. Он возвращает флаг состояния вместе с каждой строкой. Флаг True для последнего элемента нижележащего итератора:

def is_last(iterator):
    prev = next(iterator)  # immediate StopIteration possible
    for item in iterator:
        yield False, prev
        prev = item
    yield True, prev

Вы бы использовали это как

with open(...) as infile:
    for last, line in is_last(infile):
        ...
3
Mad Physicist 1 Июл 2019 в 14:20

Вы можете использовать collections.deque следующим образом:

from collections import deque


def read_file(filename):
    with open(filename) as infile:
        dq = deque([next(infile)], 1)
        for line in infile:
            yield dq[0]
            dq.append(line)

    # Last line of file.
    yield 'LAST LINE: ' + dq[0]


corpus_file = 'corpus_file.txt'

for line in read_file(corpus_file):
    print(line, end='')
2
martineau 30 Июн 2019 в 01:10

Как правило, вы не хотите пытаться выяснить это внутри цикла, скорее, вы будете знать, что достигли конца, когда цикл завершается. Если вы хотите сделать что-то особенное, если вы достигли конца (и иногда можете break выйти из цикла), вы можете добавить предложение else к for:

with open(filename) as file:
    for line in file:
        if not do_stuff(line):
            break
    else: # got to the end without breaking
        do_something_special_with_last_line(line)

3
Blckknght 29 Июн 2019 в 22:34