python - 生成器与嵌套 for 循环

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

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

输入文本文件:

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 循环。谢谢。

最佳答案

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

这有效:

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 :

The comprehension consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new container are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached.

我的粗体强调。

关于python - 生成器与嵌套 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43823524/

相关文章:

python - 为什么我们需要 gevent.queue?

python - Discord.py:希望将 message.content 读为小写,.lower() 不起作用

python - 为什么Python3守护线程在控制台中立即关闭?

python - 将用户输入变量合并为一个变量。其中之一可能不是变量

python - ''.join(random.choice(chars) for _ in range(size))

python - Dataframe.str 失败,因为整列都是空白

python - numpy 数组行主要和列主要

python-3.x - Python - KeyError(key) 被引发,但它不应该

python-3.x - Python Pandas - 根据索引、列使用字典更新行

python - GAN 判别器否认生成的模型