Python基础实现矩阵类 1
Python基础实现矩阵类 1:矩阵类,打印矩阵,矩阵加减数乘
Python基础实现矩阵类 1
总目标
Python语法基础也学了挺久的了。但一直没有什么练习的机会。突然灵光一现,毕竟我是学数学的。不如用Python基础语法来实现数学里的一些东西吧。奈何数分实现难度太高,仅依靠我学的一点点Python语法皮毛,根本无从下手。这时我想起了高代。作为高代知识的重要载体,矩阵有着许许多多的性质,而这些性质大部分与数的运算有关。这便于用基础程序实现。
本专题的总目标就是:利用Python基础语法,实现一个矩阵类,能够进行矩阵的加、减、乘、逆,数乘、转置、化阶梯型等各种矩阵运算。
本节小目标
- 定义矩阵类(Matrix)
- 让print能够打印矩阵对象
- 能够进行矩阵的加、减、数乘
定义矩阵类
好吧。首先要定义出一个矩阵类来。类名是Matrix。
class Matrix(object):
定义一个类,首先要想好构造函数。
让我们来看看矩阵的定义:
由 m × n 个数域P中的数组成的m行n列数表
从中我们可以提取出三个要素:
- m行
- n列
- 数表
所以我们的构造函数的三个参数也分别是这三个要素:
def __init__(self,m:int,n:int,matrix=None):
其中m
是矩阵的行数,类型一定要是int
.n
是矩阵的列数,类型为int
.matrix
需要是一个二维列表,默认可以不传入。
构造函数的功能大概是:
传入m
,n
,如果传入了一个由m
个长度为n
的列表组成的二维列表matrix
,那么设置这个矩阵对象的m
属性为m
,n
属性为n
,matrix
属性为matrix
.如果没有传入matrix
,那么就自动创建一个m×n的元素全为1的矩阵,设置m
,n
,matrix
等属性。
既然框架已经有了。那么就用代码开始实践吧!
init()
class Matrix(object):
"""矩阵类"""
def __init__(self, m: int, n: int, matrix=None):
"""
m:行数 n:列数
matrix:二维列表
"""
if matrix: # 传入了matrix
if is_mn_matrix(matrix, m, n): # matrix为正确的m×n二维列表
self.m = m
self.n = n
self.matrix = matrix
return
else:
print(f"矩阵形状错误,将默认创建{m}×{n}全1矩阵...")
# 没传入matrix
self.m = m
self.n = n
self.matrix = [[1 for i in range(n)] for j in range(m)] # 创建默认全一矩阵
is_mn_matrix()
其中is_mn_matrix
这个判断函数我们在类外写就行了。
def is_mn_matrix(matrix: list[list], m:int, n:int):
"""判断二维列表是否是m×n型矩阵"""
yes = True # 设置标志
if len(matrix) == m: # 行数确实是m
for i in range(m):
if len(matrix[i]) != n: # 如果有列数不是n,就返回错
yes = False
break
else: # 行数不是m,返回错
yes = False
return yes
写到这里,我们的第一步就已经完成了。我们成功编写了Matrix
类的构造函数。试验一下。
if __name__ == "__main__": #试验代码入口
a = Matrix(3, 3, [[1, 2, 3], [2, 3, 4], [5, 6, 7]])
print(a)
print(a.matrix)
b = Matrix(3, 3, [[2, 2], [4, 4]])
print(b)
print(b.matrix)
c = Matrix(3, 3)
print(c)
print(c.matrix)
运行结果没有问题:
<__main__.Matrix object at 0x0000019F22595DE0>
[[1, 2, 3], [2, 3, 4], [5, 6, 7]]
矩阵形状错误,将默认创建3×3全1矩阵...
<__main__.Matrix object at 0x0000019F22595CC0>
[[1, 1, 1], [1, 1, 1], [1, 1, 1]]
<__main__.Matrix object at 0x0000019F22595C60>
[[1, 1, 1], [1, 1, 1], [1, 1, 1]]
让print能够打印矩阵对象
上面的实验过程中,我们发现将Matrix
对象传入print()
函数,只会打印出极其难看的
<__main__.Matrix object at 0x0000019F22595C60>
我们当然希望打印一个矩阵,能直接看出它的形状和各元素排列。
str()
这个时候魔法方法__str__
就能派上用场了。
废话不多说,直接上代码:
def __str__(self):
"""打印矩阵"""
string = f"{self.m}×{self.n}矩阵:\n" #行列信息
for row in self.matrix:
for item in row:
string += f"{int(item):<3} " #每个元素占3位,左对齐
string += "\n" # 每行末换行
return string #string就是print将打印的东西
这段代码本质上就是遍历二维列表的元素,所以也没有什么难度。
但由于学的东西还是太少了,完全不知道让小数怎么对齐得好看一点,所以我选择直接把元素以整型的形式打印出来。注意matrix
属性里的元素是小数就还是小数,不会因为我打印出来是整数就会变。
试验一下:
if __name__ == "__main__":
a = Matrix(3, 3, [[1.1, 2, 3], [2.2, 3, 4], [5.5, 6, 7]])
print(a)
print(a.matrix)
运行结果挺可以的:
3×3矩阵:
1 2 3
2 3 4
5 6 7
[[1.1, 2, 3], [2.2, 3, 4], [5.5, 6, 7]]
能够进行矩阵的加、减、数乘
矩阵加减
之所以选择先实现矩阵的加减,是因为矩阵加减的规则异常简单,只需要循环遍历,对应位置的元素加减就行。
我们希望能够编写一个函数,其使用类似于:
c=a.add(b) #将矩阵b加到a上,并能返回结果(新的Matrix对象)给c,但不改变矩阵a
copy()
要实现对a的元素进行运算但又不修改a
,就需要能够复制矩阵a
对象为new
。直接new=a
是不行的。因为a.matrix
是可变数据类型列表,所以我们的Matrix
也可以算是可变数据类型,所以a
,new
的修改是同步的。不妨写一个copy
方法。
def copy(self):
"""复制"""
new = Matrix(self.m, self.n)
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] = self.matrix[i][j]
return new
有了copy
,就能实现对象复制了。
get_size()
需要注意,只有同型矩阵才能进行加减。我们不妨再实现一个get_size
方法来获取矩阵的大小。
def get_size(self):
"""返回矩阵大小"""
return self.m, self.n
异常之简单。
add/minus
有了copy
和get_size
的准备工作,现在让我们来实现矩阵的加法与减法吧。(逻辑一模一样,只是个正负号的差别。)
def add(self, other: "Matrix"):
"""加other矩阵"""
if self.get_size() != other.get_size():
print("矩阵大小不匹配!")
return
new = self.copy()
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] += other.matrix[i][j] # 对应元素相加
return new
def minus(self, other: "Matrix"):
"""减other矩阵"""
if self.get_size() != other.get_size():
print("矩阵大小不匹配!")
return
new = self.copy()
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] -= other.matrix[i][j] # 对应元素相减
return new
试验:
if __name__ == "__main__":
a = Matrix(3, 3, [[1, 2, 3], [2, 3, 4], [5, 6, 7]])
b=Matrix(3, 3, [[2, 3, 3], [3, 3, 3], [5, 2, 0]])
print(a)
print(b)
c=a.add(b)
print(a)
print(c)
d=Matrix(2,2)
e=a.add(d)
运行结果:
3×3矩阵: #a
1 2 3
2 3 4
5 6 7
3×3矩阵: #b
2 3 3
3 3 3
5 2 0
3×3矩阵: #加完后a不变
1 2 3
2 3 4
5 6 7
3×3矩阵: #c=a.add(b)
3 5 6
5 6 7
10 8 7
矩阵大小不匹配! #不同型尝试相加
no problem!
数乘
数乘就更简单了:只需要每个元素都乘k倍就行
k_multipy()
def k_multipy(self, k):
"""k数乘"""
new = self.copy()
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] *= k
return new
试验:
if __name__ == "__main__":
a = Matrix(3, 3, [[1, 2, 3], [2, 3, 4], [5, 6, 7]])
b=a.k_multipy(2)
print(a)
print(b)
运行结果:
3×3矩阵: #a
1 2 3
2 3 4
5 6 7
3×3矩阵: #b=a.k_multipy(2)
2 4 6
4 6 8
10 12 14
代码汇总
好了,本节的小目标成功达成!
def is_mn_matrix(matrix: list[list], m: int, n: int):
"""判断二维列表是否是m×n型矩阵"""
yes = True # 设置标志
if len(matrix) == m: # 行数确实是m
for i in range(m):
if len(matrix[i]) != n: # 如果有列数不是n,就返回错
yes = False
break
else: # 行数不是m,返回错
yes = False
return yes
class Matrix(object):
"""矩阵类"""
def __init__(self, m: int, n: int, matrix=None):
"""
m:行数 n:列数
matrix:二维列表
"""
if matrix: # 传入了matrix
if is_mn_matrix(matrix, m, n): # matrix为正确的m×n二维列表
self.m = m
self.n = n
self.matrix = matrix
return
else:
print(f"矩阵形状错误,将默认创建{m}×{n}全1矩阵...")
# 没传入matrix
self.m = m
self.n = n
self.matrix = [[1 for i in range(n)] for j in range(m)] # 创建默认全一矩阵
def get_size(self):
"""返回矩阵大小"""
return self.m, self.n
def add(self, other: "Matrix"):
"""加other矩阵"""
if self.get_size() != other.get_size():
print("矩阵大小不匹配!")
return
new = self.copy()
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] += other.matrix[i][j] # 对应元素相加
return new
def minus(self, other: "Matrix"):
"""减other矩阵"""
if self.get_size() != other.get_size():
print("矩阵大小不匹配!")
return
new = self.copy()
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] -= other.matrix[i][j] # 对应元素相减
return new
def k_multipy(self, k):
"""k数乘"""
new = self.copy()
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] *= k
return new
def copy(self):
"""复制"""
new = Matrix(self.m, self.n)
for i in range(self.m):
for j in range(self.n):
new.matrix[i][j] = self.matrix[i][j]
return new
def __str__(self):
"""打印矩阵"""
string = f"{self.m}×{self.n}矩阵:\n" # 行列信息
for row in self.matrix:
for item in row:
string += f"{int(item):<3} " # 每个元素占3位,左对齐
string += "\n" # 每行末换行
return string # string就是print将打印的东西
更多推荐
所有评论(0)