我正在编写代码的调试部分,所以我使用了很多 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 返回一个生成器。
当您调用 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)
因为现在您将拥有对您从生成器创建的列表的引用。
