python - 就地矩阵乘法 __imatmul__ 返回修改后的对象
问题描述
这个类很简单:
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__
?
解决方案
您的实现__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
您还可以定义__matmul__
以__imatmul__
使维护更容易:
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)
推荐阅读
- php - 如何在 php 方面验证中访问 json 子项?
- microsoft-graph-api - Microsoft Graph API 创建事件不再返回会议 ID
- mysql - MYSQL 获取按用户分组的第一(MIN)和最后(MAX)订单记录
- powershell - 如何从 invoke-webrequest 命令中过滤 .content
- python - [Django rest_framework]使用redis作为Django DRF缓存的问题
- python - Discord.py - 如果类别不存在则创建一个类别
- python - 如何在使用 Python 加载到 MySQL 之前替换 CSV 标头中的特殊字符?
- node.js - 在返回函数之前等待写入流完成
- r - 在取消列表过程中提供列的数值而不是自动列表编号
- powershell - 拒绝从 Jenkins 描述性管道访问 powershell.exe Start-Process