Python这门语言,我深有感触的是,Python 的核心特性能让我们用极少的代码实现非常多的功能,尤其是在数学运算和线性代数领域。这篇文章,我就来聊聊如何用 Python 的一些特性写出简洁优雅的数学代码,同时也会修正一些常见误区,用更严谨的方式来实现这些功能。
先说一句:如今的 Python 生态已经非常强大,像 NumPy 和 SymPy 这样的库早已覆盖了大部分数学需求,但了解 Python 本身的强大之处依然是非常有意义的。
Python 的列表推导式是一个经典的例子,它简化了我们对集合数据的操作。举个例子,如果我们想将一个向量的每个元素乘以一个标量,在其他语言中,可能需要用循环来实现,比如:
def scaled(vector, scalar):
result = []
for element in vector:
result.append(element * scalar)
return result
在 Python 中,我们可以用列表推导式将这段代码缩短为一行:
def scaled(vector, scalar):
return [x * scalar for x in vector]
更进一步,如果需要对两个向量进行逐元素相加,可以利用 zip
来迭代两个列表,并结合列表推导式:
def add_vectors(vector1, vector2):
return [x + y for x, y in zip(vector1, vector2)]
zip
的作用是将多个可迭代对象“拉链式”配对成元组,例如:
>>> list(zip([1, 2, 3], [4, 5, 6]))
[(1, 4), (2, 5), (3, 6)]
在计算向量的点积时,我们可以结合 zip
和 sum
函数,一行实现点积的计算:
def dot_product(vector1, vector2):
return sum(x * y for x, y in zip(vector1, vector2))
Python 的条件表达式同样是非常强大的工具,可以让我们用非常紧凑的方式实现逻辑判断。例如,创建一个单位矩阵(Identity Matrix):
def identity_matrix(n):
return [[1 if i == j else 0 for j in range(n)] for i in range(n)]
如果进一步了解 Python 的特性,你会发现布尔值 True
和 False
可以直接与数字进行运算,True
会被当作 1
,False
会被当作 0
。因此,上面的代码还可以简化为:
def identity_matrix(n):
return [[int(i == j) for j in range(n)] for i in range(n)]
在矩阵操作中,转置是一个常见需求。如果我们将矩阵存储为嵌套列表,可以利用 zip
和星号解包操作实现转置:
def transpose(matrix):
return [list(row) for row in zip(*matrix)]
在这里,*matrix
会将矩阵的每一行解包为单独的参数传递给 zip
,从而实现列与行的交换。
接着来看矩阵与向量相乘的操作。矩阵存储为嵌套列表时,我们可以将每一行与向量做点积,再组合成一个新向量:
def matrix_vector_multiply(matrix, vector):
return [dot_product(row, vector) for row in matrix]
如果需要计算两个点之间的欧几里得距离,公式很简单:向量差的自乘积开平方。实现上我们可以这样写:
import math
def euclidean_distance(point1, point2):
return math.sqrt(sum((x - y) ** 2 for x, y in zip(point1, point2)))
再复杂一点,假如我们要解决线性方程组 Ax = B
。尽管使用 NumPy 的 numpy.linalg.solve
是最推荐的方法,但如果需要自己实现一个简单的解算器,我们可以使用迭代方法:
def solve_linear_system(matrix, b, guess, tolerance=1e-5):
def projection(x, a, b):
scale = (b - dot_product(a, x)) / dot_product(a, a)
return [xi + scale * ai for xi, ai in zip(x, a)]
while True:
errors = [dot_product(row, guess) - bi for row, bi in zip(matrix, b)]
if max(abs(e) for e in errors) < tolerance:
break
guess = projection(guess, matrix[0], b[0])
matrix = matrix[1:] + [matrix[0]]
b = b[1:] + [b[0]]
return guess
上面代码使用了简单的投影法,并且通过“旋转”矩阵和右端向量来循环迭代。尽管这种方法效率不高,但它展示了 Python 的灵活性。
最后,矩阵求逆可以看作是解多个线性方程组的组合。每次将单位矩阵的一列作为目标向量 b
,求解相应的方程组:
def invert_matrix(matrix):
identity = identity_matrix(len(matrix))
return [solve_linear_system(matrix, col, [0] * len(matrix)) for col in identity]
这些代码展示了 Python 核心特性在数学领域的强大表达能力。从列表推导式到 zip
,再到条件表达式和解包操作,每一个功能都让代码更加简洁且可读。
虽然现代库已经让我们不需要手动实现这些功能,但理解 Python 的这些基本特性仍然能够帮助我们写出更优雅的代码。
标签:10,搞定,return,matrix,zip,Python,vector,def From: https://blog.csdn.net/2401_88796361/article/details/144194142