Python 在 print() 之后跳过 for 循环
Python skipping for-loop after print()
我正在调试我编写代码的部分,所以我使用了很多对 print
的调用来检查我的变量值。我遇到过一种情况,当打印变量时导致 Python 跳过 for
循环。
import numpy as np
import itertools as itr
(...)
class myclass():
def a_function_inside_a_class():
print('-------------')
current_size = self.get_current_size()
current_size[dimension] += 1
new_layer = [range(i) for i in current_size]
new_layer[dimension] = [current_size[dimension]]
print(new_layer)
new_layer = itr.product(*new_layer)
print(list(new_layer)) # THIS LINE CAUSES PROBLEMS
for c in new_layer:
print('for')
print(list(c))
(...)
a_function_that_causes_some_error(c)
我创建一个列表,然后使用 itertools
创建此列表的组合,然后遍历它们。
如果我像上面那样调用 a_function_inside_a_class()
, 我不会打印 for
。没有错误发生。解释器没有进入循环。
(...)
-------------
[[2], range(0, 1), range(0, 1)]
[(2, 0, 0)]
-------------
[range(0, 1), [2], range(0, 1)]
[(0, 2, 0)]
(...)
但是如果我 注释掉 #print(list(new_layer))
然后执行 for 循环并且我得到一个由其他函数引起的错误 a_function_that_causes_some_error(c)
.
-------------
[[2], range(0, 1), range(0, 1)]
for
[2, 0, 0]
Traceback (most recent call last):
(...)
list(new_layer)
不会改变new_layer
对象本身,只是创建一个列表并将其传递给print()
函数,对吗?
问题是 itertools.product
returns 一个生成器。
当您调用 print(list(new_layer))
时,您正在从生成器构建一个列表,但不要在任何地方保存对该列表的引用。
生成器本身会在将其转换为列表后耗尽,因为 list(some_generator)
在该生成器上调用 __next__
(或 next
,取决于 Python 版本)直到它升起 StopIteration
.
>>> from itertools import product
>>> new_layer = product([1,2,3], [4,5,6])
>>> new_layer
<itertools.product object at 0x7f46e90349b0>
>>> print(list(new_layer))
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
>>> print(list(new_layer))
[]
如你所见,构造列表一次后,生成器为空。
您可以使用
修复您的程序
new_layer = list(itr.product(*new_layer))
print(new_layer)
因为现在您将从生成器中获得对正在创建的列表的引用。
我正在调试我编写代码的部分,所以我使用了很多对 print
的调用来检查我的变量值。我遇到过一种情况,当打印变量时导致 Python 跳过 for
循环。
import numpy as np
import itertools as itr
(...)
class myclass():
def a_function_inside_a_class():
print('-------------')
current_size = self.get_current_size()
current_size[dimension] += 1
new_layer = [range(i) for i in current_size]
new_layer[dimension] = [current_size[dimension]]
print(new_layer)
new_layer = itr.product(*new_layer)
print(list(new_layer)) # THIS LINE CAUSES PROBLEMS
for c in new_layer:
print('for')
print(list(c))
(...)
a_function_that_causes_some_error(c)
我创建一个列表,然后使用 itertools
创建此列表的组合,然后遍历它们。
如果我像上面那样调用 a_function_inside_a_class()
, 我不会打印 for
。没有错误发生。解释器没有进入循环。
(...)
-------------
[[2], range(0, 1), range(0, 1)]
[(2, 0, 0)]
-------------
[range(0, 1), [2], range(0, 1)]
[(0, 2, 0)]
(...)
但是如果我 注释掉 #print(list(new_layer))
然后执行 for 循环并且我得到一个由其他函数引起的错误 a_function_that_causes_some_error(c)
.
-------------
[[2], range(0, 1), range(0, 1)]
for
[2, 0, 0]
Traceback (most recent call last):
(...)
list(new_layer)
不会改变new_layer
对象本身,只是创建一个列表并将其传递给print()
函数,对吗?
问题是 itertools.product
returns 一个生成器。
当您调用 print(list(new_layer))
时,您正在从生成器构建一个列表,但不要在任何地方保存对该列表的引用。
生成器本身会在将其转换为列表后耗尽,因为 list(some_generator)
在该生成器上调用 __next__
(或 next
,取决于 Python 版本)直到它升起 StopIteration
.
>>> from itertools import product
>>> new_layer = product([1,2,3], [4,5,6])
>>> new_layer
<itertools.product object at 0x7f46e90349b0>
>>> print(list(new_layer))
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
>>> print(list(new_layer))
[]
如你所见,构造列表一次后,生成器为空。
您可以使用
修复您的程序new_layer = list(itr.product(*new_layer))
print(new_layer)
因为现在您将从生成器中获得对正在创建的列表的引用。