我对使用返回numpy数组的生成器有以下奇怪的行为。在实际应用中,我使用scipy.sparse来实现迭代线性代数求解器:下面是一个精简版本。我有以下内容:
import numpy as np
def iterable(n):
nc = np.array([0,0,0])
yield nc
while nc[0] < n:
nc += 1
yield nc
raise StopIteration
当我尝试使用输出
填充列表时iter = iterable(4)
print list(iter)
我得到了
$ python itertest.py
[array([4, 4, 4]), array([4, 4, 4]), array([4, 4, 4]), array([4, 4, 4]), array([4, 4, 4])]
,即最终收益率的结果&#39;重复了n次。如果我将yield nc
更改为yield nc.tolist()
,那么我会得到预期的结果。如果可能的话,我想避免这种情况,因为我最终不得不重新制作阵列。发生了什么事?
提前致谢!
答案 0 :(得分:1)
你只创建一个ndarray。执行nc += 1
后,您可以将其到位进行修改。因此,后面的迭代修改已经产生的相同数组,然后再次产生它。
您可以通过一次打印一个生成的数组来看到这一点:
>>> it = iterable(3)
>>> x = next(it)
>>> print x
[0 0 0]
>>> y = next(it)
>>> print y
[1 1 1]
>>> print x # x changed!
[1 1 1]
>>> x is y
True
您可以看到第二次迭代会更改第一次迭代时产生的对象,因为它们是同一个对象。
要解决此问题,请将nc += 1
行更改为nc = nc + 1
。这将在每次迭代时创建一个新数组。