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)

因为现在您将从生成器中获得对正在创建的列表的引用。