Python 使用 input() 逐行遍历标准输入

Posted

技术标签:

【中文标题】Python 使用 input() 逐行遍历标准输入【英文标题】:Python iterate over stdin line by line using input() 【发布时间】:2016-05-07 21:59:44 【问题描述】:

我正在尝试从控制台获取由换行符分隔的多个名称并将它们放入一个变量中。假设我想永远从终端获取输入(稍后我将添加一些代码以跳出循环)。我知道如何使用 while 循环和递归来做到这一点,但我希望能够使用 for 循环来做到这一点。

在下面的示例中,当我从终端获取"peter" 作为输入时,我一次获取的是每个字母而不是整行:

for name in input():
    print(name)

现在,如果我使用 sys.stdinname 变量将变为 "peter\n"

for name in sys.stdin:
    print(name)

有没有简单的方法让input()"name" 整行而不是单个字符?或者只是由于使用for in 的性质,我将遍历输入中的字符?以这种方式获取输入是否存在任何固有的风险/问题?在这种情况下是否有一种“标准”的方式来获取输入?

我在 Ubuntu 15.10 上使用 Python 3.5.1。

【问题讨论】:

input() 返回一个可迭代的字符串,因此当您尝试对其进行迭代时,您会一个一个地获取每个字符。 好吧,这是有道理的。 input() 返回一个字符串。那么 sys.stdin 是否返回一个逐行迭代的缓冲区? 因为 sys.stdin 返回一个类似对象的文件,当迭代时,它将包含输入的每一行。 @PeterH sys.stdin isn't a function,它实际上是一个文件对象,系统使用它来获取标准输入,因此for name in sys.stdin 的行为就像它对文件所做的那样:逐行读取. 酷是有道理的。如果我使用'for name in sys.stdin',当输入正确结束时会退出循环? 【参考方案1】:

我不建议您这样做,但您可以创建一个生成器以在 for 循环中使用,以逐行遍历输入:

def getlines():
    while True:
        yield input()

for name in getlines():
    print(name)
    ## Remember to break out of the loop at some point

【讨论】:

对不起,如果我不清楚。我试图在终端中用换行符分隔每个名称不止一次。【参考方案2】:

您可以换行stdin 以去除换行符;如果你可以去掉所有尾随空格(通常没问题),那么它只是:

for name in map(str.rstrip, sys.stdin):
    ...

您使用的是 Py3,因此可以按原样运行;如果你在 Py2 上,你需要添加一个导入,from future_builtins import map,所以你会得到一个基于 map 的惰性生成器(它会根据请求生成行,而不是在它之前啜饮 stdin结束,然后返回所有行的list)。

如果您需要限制换行符,生成器表达式可以做到:

for name in (line.rstrip("\r\n") for line in sys.stdin):
    ...

或通过导入允许map 将工作推送到 C 层以获得(稍微)更快的代码(每行比genexpr 快30 纳秒,但仍然比无参数选项慢40 ns在这个答案的顶部):

from operator import methodcaller

for name in map(methodcaller('rstrip', '\r\n'), sys.stdin):
    ...

与第一个解决方案一样,在 Py2 上,确保从 future_builtins 获取 map

【讨论】:

以上是关于Python 使用 input() 逐行遍历标准输入的主要内容,如果未能解决你的问题,请参考以下文章

Python常用标准库之fileinput

python 编程问题:获得用户输入的一个字符串,将字符串按照空格分隔,然后逐行打印出来

python 计算标准体重程序

如何逐行读取大文件?

Python中输入和输出(打印)数据

python逐行读写