Python 使用 input() 逐行迭代标准输入

Python iterate over stdin line by line using input()

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

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

for name in input():
    print(name)

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

for name in sys.stdin:
    print(name)

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

我在 Ubuntu 15.10 上使用 Python 3.5.1。

我不建议你这样做,但你可以创建一个生成器以在 for 循环中逐行迭代输入:

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

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

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

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

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

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

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

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

from operator import methodcaller

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

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