我正在调试编写代码的一部分,因此我使用了大量调用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()
函数,是吗?
答案 0 :(得分:5)
问题是itertools.product
返回一个生成器。
当您致电print(list(new_layer))
时,您正在构建一个来自生成器的列表,但不要在任何地方保存对该列表的引用。
生成器本身在将其转换为列表后会耗尽,因为list(some_generator)
会在该生成器上调用__next__
(或next
,具体取决于Python版本),直到它升起{{1} }}
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))
[]
因为现在您将引用您从生成器创建的列表。