2014-12-30 6 views
-1

EDIT: Я в конечном итоге, глядя вверх решения вопроса я являюсь «дубликат» из, и крафта следующий фрагмент кода:Python зсапЕ подобный вход

import sys 
from collections import deque 

_input=deque([]) 

def read_word(): 
    global _input 
    while len(_input)==0: 
     line=sys.stdin.readline().split() 
     for word in line: 
      _input.append(word) 
    return _input.popleft() 

def read_int(): 
    return int(read_word()) 

ORIGINAL ВОПРОС:

Я хочу написать некоторые программы, считывающие ввод из stdin в Python. Но обработка ввода меня убивает - я не вижу хороший способ сканирования данных, которые не выровнены по строкам. Например, если я должен сканировать целое число N, а затем N слов для обработки, в C++ Я хотел бы сделать это следующим образом:

int N; 
char str[100]; 
scanf("%d",&N); 
for(int i=0;i<N;i++){ 
    scanf("%s",str); 
    //do stuff with str 
} 

Эта программа будет сканировать все из следующих входных точно таким же образом, :

//input 1: 
3 word1 word2 word3 
//input 2: 
3 
word1 word2 word3 
//input 3: 
3 
word1 
word2 
word3 
//input 4: 
3 word1 word2 
word3 

Мне нравится гибкость C-подобный зсапЕ дает мне, и я хотел бы видеть что-то подобное в Python тоже. Я не могу использовать input(), потому что он попытался бы проанализировать строки как синтаксис Python (возможно, в итоге со словарем или что-то в этом роде), а raw_input() работает с линиями, заканчивающимися в линии. Функция sys.stdin.read() тоже не очень хороша, потому что она ждет, пока не будет указан весь ввод (и я могу отображать частичные результаты в реальном времени). Единственный способ реализовать такую ​​функциональность - использовать sys.stdin.readline() в цикле, пытаясь разобрать каждую строку независимо, до тех пор, пока все нужные слова не будут проанализированы. Но это не очень изящное решение, и оно также имеет некоторые недостатки - например, если упомянутая выше примерная программа должна вводить еще одну вещь в ее дальнейшие действия, и это слово или номер были указаны в той же строке, что и последнее слово, программа Python не будет анализировать ее должным образом.

Проблемные вход будет:

//input 5: 
3 word1 word2 
word3 next_input 

Слово «next_input» будет «проглотил» функцией Readline(), даже если это может понадобиться программой позже. Опять же, это можно обойти, предоставив временный буфер input_yet_to_be_parsed_but_already_inputted, но вскоре он станет очень ошибочным кодом. Есть ли действительно «питонический» способ сделать это? Или я пропущу что-то очевидное?

+0

"в C++ Я хотел бы сделать это так" - это не C++ ... это C. – user530873

+0

хорошо, но в C++ есть 'CIN >> A >> б;' синтаксис в любом случае, который сканирует только одно слово за раз, поэтому вопрос остается верным. – akrasuski1

ответ

0

Почему бы не использовать модуль re для регулярных выражений?

Ваш пример будет отображен в регулярном выражении, как это:

>>> pattern = re.compile(r'^(\d)*') 
>>> pattern.match('3 word1').group(1) 
'3' 

Если вам нужны остальные данные для последующего использования, как о ловле его в качестве второго Gorup?

>>> pattern = re.compile(r'^(\d)*(.*)') 
>>> match = pattern.match('3 lol') 
>>> "matched: " + match.group(1) + ", rest: " + match.group(2) 
'matched: 3, rest: lol' 
+1

Хорошо, но как вы получаете первый вход от stdin? Я хотел бы, чтобы вы специально рассмотрели окончательный выпуск (ввод 5) – akrasuski1

+0

@ akrasuski1, см. Правки, регулярные выражения могут усложняться, так как ввод получает больше copmlex, но я помню, что у 'scanf' есть это свойство. Вы можете получить доступ к «остатку» данных, сопоставив его последним. –

+0

'pattern.match ('3 word1'). Group (1)' возвращает строку '' 3'', которая почти не отличается от 'scanf ("% d ", &N);', которая читает из stdin и сохраняет целочисленное значение в целочисленную переменную 'N'. – martineau

Смежные вопросы