python生成器返回ndarray

时间:2014-04-16 20:36:15

标签: python numpy iterator generator

我对使用返回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(),那么我会得到预期的结果。如果可能的话,我想避免这种情况,因为我最终不得不重新制作阵列。发生了什么事?

提前致谢!

1 个答案:

答案 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。这将在每次迭代时创建一个新数组。