2013-05-06 2 views
4

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

Теперь я хочу сделать то же самое, но для разделенных пробелами файлов (а не только для строк новой строки). Например, рассмотрим файл f с содержанием

token1 token2 

token3       token4 


     token5 

Так я ищу какой-либо функции readtoken() таким образом, что после открытия f, первый вызов f.readtoken() возвращается token1, второй вызов Retuns token2 и т.д.

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

Я был почти уверен, что это должно быть возможно «из коробки» со стандартной библиотекой. Однако я не нашел подходящей функции или способа переопределить разделители для readline().

ответ

7

Вам необходимо создать функцию обертки; это достаточно легко:

def read_by_tokens(fileobj): 
    for line in fileobj: 
     for token in line.split(): 
      yield token 

Обратите внимание, что .readline() не только читать файл символ за символом новой строки до тех пор, пока не встретится; файл считывается в блоках (буфере) для повышения производительности.

Вышеупомянутый метод считывает файл по строкам, но дает результат разбивки по пробелам. Используйте это нравится:

with open('somefilename') as f: 
    for token in read_by_tokens(f): 
     print(token) 

Поскольку read_by_tokens() является генератор, вам необходимо либо петли непосредственно над результатом функции или использовать next() function, чтобы получить жетоны, один за другим:

with open('somefilename') as f: 
    tokenized = read_by_tokens(f) 

    # read first two tokens separately 
    first_token = next(tokenized) 
    second_token = next(tokenized) 

    for token in tokenized: 
     # loops over all tokens *except the first two* 
     print(token) 
+0

Обратите внимание, что это (+1), поэтому он работает как 'для строки в f', а не' f.readline() ' –

+0

@HenryKeiter: вы действительно должны использовать файл как итератор в любом случае, вместо использования' .readline() 'вызовов, но да. –

+0

Конечно. Я просто хотел, чтобы это было ясно, так как он специально спрашивает о 'readline'. Ваши правки сделали мой комментарий лишним, хотя :) –