1

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

输入文本文件:

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 循环的仅生成器解决方案。谢谢你。

4

1 回答 1

2

您颠倒了循环的顺序。生成器表达式(像所有 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())

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

请参阅表达式参考文档

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

大胆强调我的。

于 2017-05-06T17:42:36.133 回答