【问题标题】:Generator always returning the same element [duplicate]生成器总是返回相同的元素[重复]
【发布时间】:2017-09-20 08:09:04
【问题描述】:

我有一个代码如下:

def xgauss(self):

    m, n = self.m, self.n

    M = self.copy()

    for k in range(n):
        for i in range(k + 1, m):
            yield M
            if not likezero(M[i][k]):
                lam = M[i][k] / M[k][k]
                M[i] = M[i] - lam * M[k]

    yield M

现在足以说如果值小于精度(用于数值比较),likezero 返回 true ;-)

我的目标是返回高斯消除算法的每次迭代以供学习(课堂)。

我有一些测试输入:

In [77]: A
Out[77]: 
Matrix([
        [     1,      4,      1],
        [     1,      6,     -1],
        [     2,     -1,      2]
      ])

In [78]: Ab
Out[78]: 
Matrix([
        [      1,       4,       1,       7],
        [      1,       6,      -1,      13],
        [      2,      -1,       2,       5]
      ])

奇怪与否,当我通过 Matrix Ab 调用生成器时(通过 A 我也得到相同的行为),我得到:

In [76]: list(Ab.xgauss())
Out[76]: 
[Matrix([
         [      1,       4,       1,       7],
         [      0,       2,      -2,       6],
         [      0,       0,      -9,      18]
       ]), Matrix([
         [      1,       4,       1,       7],
         [      0,       2,      -2,       6],
         [      0,       0,      -9,      18]
       ]), Matrix([
         [      1,       4,       1,       7],
         [      0,       2,      -2,       6],
         [      0,       0,      -9,      18]
       ]), Matrix([
         [      1,       4,       1,       7],
         [      0,       2,      -2,       6],
         [      0,       0,      -9,      18]
       ])]

那是正确答案(应该只是最后一次迭代),但是我看不到每一步,生成器在所有迭代中返回矩阵结果。我不知道会发生什么。

【问题讨论】:

    标签: python generator linear-algebra


    【解决方案1】:

    在您的生成器中,您有一个值 M,它是您的类的一个实例。您每次都产生相同的对象。在每次迭代中,您都在修改对象。生成器不会产生 M 的副本,它会产生对 M 的引用,就像函数不返回副本,它们返回引用一样。

    当您制作一个生成器结果的列表时,您正在制作一个包含许多对同一对象的引用的列表。打印列表会多次显示同一个对象,显示其最后状态。

    顺便说一句,Python 的这种行为(没有隐式副本,大量引用)在我的 PyCon 演讲中进行了更详细的介绍:Python Names and Values

    【讨论】:

    • 非常酷的幻灯片,即使是理解这些概念的人。不过,可能需要添加免责声明。
    猜你喜欢
    • 2013-04-17
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多