如何使用List comprehension实现矩阵的对称k*k子矩阵随机采样?
问题描述
给定n阶矩阵:
mat = [[a_11, a_12, ... , a_1n], [a_21, a_22, ... , a_2n], ... [a_n1, a_n2, ... , a_nn]]
需要从中生成一个k*k的方形子矩阵(1 < k < n),要求若选中元素mat[x][y],则必须同时选中mat[y][x]。子矩阵的形式为:
submat = [[mat[x_1][x_1], mat[x_1][x_2], ... mat[x_1][x_k]], [mat[x_2][x_1], mat[x_2][x_2], ... mat[x_2][x_k]], ... [mat[x_k][x_1], mat[x_k][x_2], ... mat[x_k][x_k]]]
其中x₁、x₂、…、x_k是从0到n-1范围内随机选取的互不相同的整数。
举个例子,当n=4时的矩阵:
mat = [[1, 5, 7, 0], [2, 4, 3, 1], [4, 9, 8, 1], [1, 0, 9, 3]]
取k=2时,可能得到的采样结果如下:
[[1, 1], [0, 2]]
我自己尝试了以下代码:
import random ordDet = [0, 1, 2, 3] random.shuffle(ordDet) submat = [ [mat[ordDet[0]][ordDet[0]], mat[ordDet[0]][ordDet[1]]], [mat[ordDet[1]][ordDet[0]], mat[ordDet[1]][ordDet[1]]] ]
请问是否可以使用列表推导式来实现该需求?
解决方案
当然可以用列表推导式实现,还能让代码更简洁通用(无需硬编码k=2的情况),具体步骤如下:
- 随机选取k个不重复索引:用
random.sample直接从range(n)中抽取k个元素,比手动打乱再切片更高效。 - 嵌套列表推导式生成子矩阵:外层遍历选中的行索引,内层遍历选中的列索引,取出对应位置的元素。
完整代码示例:
import random n = 4 k = 2 mat = [[1, 5, 7, 0], [2, 4, 3, 1], [4, 9, 8, 1], [1, 0, 9, 3]] # 随机选取k个互不重复的索引 selected_indices = random.sample(range(n), k) # 用列表推导式生成符合要求的子矩阵 submat = [[mat[i][j] for j in selected_indices] for i in selected_indices] print(submat)
这种写法既满足mat[x][y]与mat[y][x]同时被选中的要求,又简化了代码结构,还支持任意合法的k值(只要1<k<n)。
内容的提问来源于stack exchange,提问作者Bilqiz Gairbekov
相关产品推荐
相关产品推荐

