2014-12-30 95 views
-1

编辑: 最后我找了解决方案,我是的“重复”的问题,并起草下面的代码片段:Python的类似scanf输入

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()) 

原题:

我想写一些读取Python中stdin输入的程序。但输入处理正在让我失望 - 我没有看到一种很好的方式来扫描线条中不完美的数据。 例如,如果我必须扫描的整数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类scanf给我的灵活性,我也希望在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的临时缓冲区来解决,但它很快会变成非常有问题的代码。有没有真正的“pythonic”方式来做到这一点?还是我错过了明显的东西?

+0

“在C++中我会做这样的” - 这不是C++ ...这是C. – user530873

+0

OK,但在C++中有'CIN >> A >> B;'语法,无论如何,它扫描只是一次一个字,所以问题保持有效。 – 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

好的,但你如何从标准输入首先得到输入?我希望你特别解决最后一个问题(输入5) – akrasuski1

+0

@ akrasuski1,参见编辑,正则表达式可能会变得更复杂,因为输入获得更多的copmlex,但我记得'scanf'也具有该属性。您可以通过最后匹配来访问数据的“休息”。 –

+0

'pattern.match('3 word1')。group(1)'返回字符串''3'',它与scanf(“%d”,&N);''从stdin中读取并存储整数值变成整数变量'N'。 – martineau