就地矩阵乘法uu imatmul uuuu返回修改后的对象

2024-10-04 03:21:22 发布

您现在位置:Python中文网/ 问答频道 /正文

课程非常简单:

class Matrix(object):
    def __init__(self, values):
        self.values = values

    def __matmul__(self, other):
        return Matrix(Matrix.multiply(self.values, other.values))

    def __rmatmul__(self, other):
        return Matrix(Matrix.multiply(self.values, other.values))

    def __imatmul__(self, other):
        return self.__matmul__(other)

    @staticmethod
    def multiply(mat1, mat2):
        return [[sum(mat1 * mat2 for mat1, mat2 in zip(mat1_row, mat2_col))
                 for mat2_col in zip(*mat2)]
                for mat1_row in mat1]

    def __repr__(self):
        return f'<Matrix values="{self.values}">'

出于某种原因,在使用__imatmul__dunder方法时,我无法使其转换初始矩阵-ID不同:

mat1 = Matrix([[11, 12], [13, 14]])
orig_id_mat1 = id(mat1)
print(f'mat1: {mat1}, id: {orig_id_mat1}')
mat2 = Matrix([[1, 2], [3, 4]])
orig_id_mat2 = id(mat2)
print(f'mat2: {mat2}, id: {orig_id_mat2}')

mat1 @= mat2
modif_id_mat1 = id(mat1)
print(f'mat1: {mat1}, id: {modif_id_mat1}')

输出:

mat1: <Matrix values="[[11, 12], [13, 14]]">, id: 24458192
mat2: <Matrix values="[[1, 2], [3, 4]]">, id: 24458384
mat1: <Matrix values="[[47, 70], [55, 82]]">, id: 24458608

__imatmul__的实现中应该改变什么


Tags: inselfidforreturndefmatrixmultiply
1条回答
网友
1楼 · 发布于 2024-10-04 03:21:22

您的__imatmul__实现只是__matmul__的别名。它没有在适当的位置执行任何操作,因为您没有对其进行编码

首先,您应该了解操作符的就地版本的作用。表达式a @= b通常(但不总是)等同于a = type(a).__imatmul__(a, b)。这只是另一个函数调用。这样,您就可以对不可变对象执行“就地”操作,创建新结果但保留名称

您对__mult__的调用正是这样做的:它创建并返回一个新对象,您可以用它替换矩阵

在适当的位置执行操作的一个简单方法是

def __imatmul__(self, other):
    self.values = self.multiply(self.values, other.values)
    return self

您还可以根据__imatmul__定义__matmul__,以简化维护:

def __matmul__(self, other):
    new = type(self)(self.values)
    return type(new).__imatmul__(new, other)

最后,您可能需要修复__rmatmul__的实现:

def __rmatmul__(self, other):
    return type(self).__matmul__(other, self)

相关问题 更多 >