生成器与嵌套 for 循环
generator versus nested for loop
我有两种方法可以对文本文件中的数字求和。第一个有效,第二个无效。谁能解释一下第二个有什么问题?
输入文本文件:
The quick brown 123
fox 456 jumped over
the 789 lazy dog.
方法一:
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)。
方法二:
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 中的生成器不好。我不需要关于 other 在文本文件中累加数字的方法的建议。我想知道是否有没有标准 for 循环的仅生成器解决方案。谢谢。
您颠倒了循环的顺序。生成器表达式(与所有 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:
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.
大胆强调我的。
我有两种方法可以对文本文件中的数字求和。第一个有效,第二个无效。谁能解释一下第二个有什么问题?
输入文本文件:
The quick brown 123
fox 456 jumped over
the 789 lazy dog.
方法一:
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)。
方法二:
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 中的生成器不好。我不需要关于 other 在文本文件中累加数字的方法的建议。我想知道是否有没有标准 for 循环的仅生成器解决方案。谢谢。
您颠倒了循环的顺序。生成器表达式(与所有 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:
The comprehension consists of a single expression followed by at least one
for
clause and zero or morefor
orif
clauses. In this case, the elements of the new container are those that would be produced by considering each of thefor
orif
clauses a block, nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached.
大胆强调我的。