【问题标题】:How to read line by line from stdin in python如何从python中的stdin逐行读取
【发布时间】:2014-01-15 23:18:40
【问题描述】:

每个人都知道如何在 C 中计算来自 STDIN 的字符。但是,当我尝试在 python3 中这样做时,我发现这是一个难题。 (counter.py)

import sys
chrCounter = 0

for line in sys.stdin.readline():
    chrCounter += len(line)

print(chrCounter)

然后我尝试通过

测试程序
python3 counter.py < counter.py

答案只是第一行“import sys”的长度。事实上,程序只从标准输入读取第一行,并丢弃其余的。

如果我用 sys.stdin.read() 代替 sys.stdin.readline 就可以了

import sys
print(len(sys.stdin.read()))

但是,很明显,该程序不适合大输入。请给我一个优雅的解决方案。谢谢!

【问题讨论】:

    标签: python stdin


    【解决方案1】:

    更简单:

    for line in sys.stdin:
        chrCounter += len(line)
    

    类文件对象sys.stdin会自动逐行迭代;如果你在上面调用.readline(),你只会读取第一行(并逐个字符地迭代);如果您调用read(),那么您会将整个输入读入单个字符串并逐个字符地迭代那个

    【讨论】:

      【解决方案2】:

      Tim Pietzcker 的答案是正确的,恕我直言。有两种类似的方法可以做到这一点。使用:

      for line in sys.stdin:
      

      for line in sys.stdin.readlines():
      

      第二个选项更接近您的原始代码。通过使用例如,这两个选项之间的区别很明显。对 for 循环体的以下修改并使用键盘输入

      for line in sys.stdin.readlines():
          line_len = len(line)
          print('Last line was', line_len, 'chars long.')
          chrCounter += len(line)
      

      如果您使用第一个选项 (for line in sys.stdin:),则在您按 Enter 后会立即处理这些行。

      如果您使用第二个选项 (for line in sys.stdin.readlines():),则首先读取整个文件,分成几行,然后才对其进行处理。

      【讨论】:

      • 你能解释一下right after you hit enter是什么意思吗?我有一个 shell 脚本,它逐行打印输出,如果我使用管道 ($ build.sh | my-python-file.py) 使用此方法 for line in sys.stdin: 使用它,我什么也得不到,但第二个选项工作正常。
      • 已经有一段时间了,因为我回答了这个问题。 “在你按下回车后”我的意思是“一旦从标准输入读取换行符,即一旦文件的迭代器准备好为调用代码提供下一行。我无法说出为什么第一个方法不适用于您的情况,但是第二种方法可能会等到所有行都生成后,然后将它们通过管道传输到 my-python-file.py ,并在其中一次处理它们。
      • 好的,非常感谢。如果我得到任何线索,我将调查为什么选项 1 对我不起作用并在此处发布。
      【解决方案3】:

      如果我只是想要一个字符数,我会一次读取块而不是一次读取行:

      # 4096 chosen arbitrarily. Pick any other number you want to use.
      print(sum(iter(lambda:len(sys.stdin.read(4096)), 0)))
      

      【讨论】:

        猜你喜欢
        • 2012-08-11
        • 2012-04-09
        • 2011-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-22
        相关资源
        最近更新 更多