生成器总是返回相同的元素
Generator always returning the same element
我有一个代码如下:
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 return为真 ;-)
我这里objective为了学习(课堂)return每次迭代高斯消元算法。
我有一些测试输入:
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]
])]
这是正确答案(应该只是最后一次迭代),但我看不到每一步,生成器 return 是所有迭代中的矩阵结果。我不知道会发生什么。
在您的生成器中,您有一个值 M,它是 class 的一个实例。您每次都产生相同的对象。在每次迭代中,您都在修改对象。生成器不生成 M 的副本,它生成对 M 的引用,就像函数不 return 复制一样,它们 return 引用。
当您制作生成器结果的列表时,您正在制作一个包含对同一对象的许多引用的列表。打印列表多次显示同一个对象,显示其最后状态。
顺便说一句,Python 的这种行为(没有隐式副本,大量引用)在我的 PyCon 演讲中有更详细的介绍:Python Names and Values.
我有一个代码如下:
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 return为真 ;-)
我这里objective为了学习(课堂)return每次迭代高斯消元算法。
我有一些测试输入:
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]
])]
这是正确答案(应该只是最后一次迭代),但我看不到每一步,生成器 return 是所有迭代中的矩阵结果。我不知道会发生什么。
在您的生成器中,您有一个值 M,它是 class 的一个实例。您每次都产生相同的对象。在每次迭代中,您都在修改对象。生成器不生成 M 的副本,它生成对 M 的引用,就像函数不 return 复制一样,它们 return 引用。
当您制作生成器结果的列表时,您正在制作一个包含对同一对象的许多引用的列表。打印列表多次显示同一个对象,显示其最后状态。
顺便说一句,Python 的这种行为(没有隐式副本,大量引用)在我的 PyCon 演讲中有更详细的介绍:Python Names and Values.