【问题标题】:generator versus nested for loop生成器与嵌套 for 循环
【发布时间】:2017-10-05 00:46:20
【问题描述】:

我有两种方法可以对文本文件中的数字求和。第一个有效,第二个无效。谁能解释一下第二个有什么问题?

输入文本文件:

The quick brown 123
fox 456 jumped over
the 789 lazy dog.

方法#1:

total = 0
for line in open(fn):
    numbers = (int(block) for block in line.split() if block.isdigit())
    total += sum(numbers)
print('total: ', total)

这给出了正确答案 1368 (= 123 + 456 + 789)。

方法#2:

numbers = (int(block) for block in line.split() for line in open(fn) if block.isdigit())
total = sum(numbers)
print('total: ', total)

这会产生错误:

NameError: name 'line' is not defined

我在玩生成器,所以问题实际上是关于为什么方法 #2 中的生成器不好。我不需要关于在文本文件中添加数字的其他方法的建议。我想知道是否有没有标准 for 循环的仅生成器解决方案。谢谢。

【问题讨论】:

  • for block in line.split() 放在for line in open(fn)之后

标签: python python-3.x generator generator-expression


【解决方案1】:

您颠倒了循环的顺序。生成器表达式(像所有 Python 理解语法变体一样)以 块嵌套顺序从 从左到右列出循环

这行得通:

numbers = (int(block) for line in open(fn) for block in line.split() if block.isdigit())

因为它与普通for 循环的嵌套顺序相匹配(只有前面的每次迭代表达式):

numbers = (int(block)
    for line in open(fn)
        for block in line.split()
            if block.isdigit())

您的代码试图在for line in open(fn) 循环执行并设置line 之前访问line.split()

expressions reference documentation

理解由一个表达式组成,后跟至少一个for 子句和零个或多个forif 子句。在这种情况下,新容器的元素是通过将每个 forif 子句视为一个块,从左到右嵌套并将表达式计算为每次到达最里面的块时产生一个元素。

我的大胆强调。

【讨论】:

  • 谢谢。现在说得通了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2014-10-07
  • 2020-05-19
  • 1970-01-01
  • 1970-01-01
  • 2016-09-15
  • 2015-09-30
相关资源
最近更新 更多