在Python矩阵算法中修改列表

在Python矩阵算法中修改列表,python,algorithm,list,Python,Algorithm,List,我正在通过一些算法挑战来获得更多的Python实践。我遇到了一个需要在python矩阵(列表列表)中更改值的问题 我的方法有两个方面:1)首先找到矩阵中的所有零,并用“x”替换该值。2) 一旦发生这种情况,循环遍历所有列表并找到现有“x”的索引,然后使用该索引值并在其他列表中搜索它。。如果该数字“低于”现有的“x”,则将该数值替换为“x”。。希望这是有道理的。我已经记下了第一部分,我尝试了很多不同的方法来写第二部分,但是现在我遇到了一个错误。。我觉得我很亲近。我还觉得我的代码效率很低(我是Pyt

我正在通过一些算法挑战来获得更多的Python实践。我遇到了一个需要在python矩阵(列表列表)中更改值的问题

我的方法有两个方面:1)首先找到矩阵中的所有零,并用“x”替换该值。2) 一旦发生这种情况,循环遍历所有列表并找到现有“x”的索引,然后使用该索引值并在其他列表中搜索它。。如果该数字“低于”现有的“x”,则将该数值替换为“x”。。希望这是有道理的。我已经记下了第一部分,我尝试了很多不同的方法来写第二部分,但是现在我遇到了一个错误。。我觉得我很亲近。我还觉得我的代码效率很低(我是Python新手),所以如果有更有效的方法,请告诉我

我理解这个错误的意思,但是我很难在得到正确答案的同时修复它。错误是索引超出了范围

我的代码:

def matrixElementsSum(matrix):
    numList = len(matrix) # essentially the number of 'rows' -> number of lists
    numCol = len(matrix[0]) # number of values in each list

    # replace 0's in each list with 'x'
    for x in matrix:
        if x.count(0) > 0:
            for index, i in enumerate(x):
                if i == 0:
                    x[index] = 'x'

    for x in matrix:
        for y in matrix[x]:
            if(matrix[x][y] == 'x'):
                x_ind = y
                for z in matrix:
                    if(z < x):
                        matrix[z][x_ind] = 'x'
     print(matrix)

您仍然需要以某种方式使用嵌套for循环,因为您正在迭代列表,但是您可以使用列表理解稍微简化逻辑

def solver(matrix):
     mx = [[v if v else 'x' for v in row] for row in matrix]
     mxx = [[v1 if v2 else 'x' for v1, v2 in zip(row1, row2)] for row1, row2 in zip(mx[1:], matrix)]
     return mx[:1] + mxx
我首先迭代该矩阵,并将新矩阵中的“0”替换为“x”mx

mx = [[v if v else 'x' for v in row] for row in matrix]
mxx = [[v1 if v2 else 'x' for v1, v2 in zip(row1, row2)] for row1, row2 in zip(mx[1:], matrix)]
这只是一个嵌套的列表理解,我们对每一行的每一个元素、每一个矩阵的每一行进行操作。
。。。如果。。。否则…
就是经典的三元运算符。如果
v
保持不变(在本例中不是零),那么它将计算为“If”之前的值,否则它将计算为“else”之后的值-在本例中为
'x'

然后我重复这个过程,但将行偏移1,这样我就可以检查上面的元素现在是否是
“x”

这里有点不对劲。让我们从“外部”开始,以我们的方式进入

... for row1, row2 in zip(mx[1:], matrix)
这会将新矩阵与原始矩阵按一(使用
[1::
切片表示法)进行压缩。因此,它返回一个iterable函数,该函数等价于以下列表:

[(mx_row1, matrix_row0), (mx_row2, matrix_row1), (mx_row3, matrix_row2), ...]
这允许我们同时提取给定行及其上方的行,如
row1
row2
。然后是另一半-

[v1 if v2 else 'x' for v1, v2 in zip(row1, row2)]
-在每行的每个元素上重复类似的过程,而不是在每矩阵的每行上重复类似的过程。我们不会像偏移
mx
矩阵的行那样偏移这两行中的元素,但在其他方面,逻辑是相同的。然后,我们再次与三元运算符进行比较,看看上面的元素是否为
0
,如果是,则计算为
'x'
。我们可以很容易地将它更改为将
mx
的每行的每个元素与
'x'
进行比较,而不是将
matrix
0
进行比较,但我决定反映第一个列表理解

一旦我有了这个新的矩阵
mxx
,我只需在
mx
的第一行前面加上前缀,因为我们在抵消比较时实际上跳过了那一行。结果是一个矩阵,其中包含所有
0
s,下面的元素替换为
“x”
s


根据注释中的说明,如果您希望标记一个
“x”
,如果上述任何元素都是
0
,而不仅仅是上面的元素,您可以通过从矩阵的该列中取一片并使用
all()
内置来查看是否有
0
。修订代码如下

def solver(matrix):
    return [[v if all(col) else 'x' for v, col in zip(row, zip(*matrix[:idx]))] for idx, row in enumerate(matrix, 1)]

你忘了告诉别人错误消息是什么。很抱歉,错误消息是索引超出范围-我将编辑主要帖子如果x.count(0)>0:,那么
的意义是什么?无论如何,您正在尝试使用矩阵中的值将x索引到矩阵中:
用于矩阵中的x:。。。对于矩阵[x]
中的y,
x
将是一个
列表
,一个“矩阵”中的“行”哇,这非常有效!我以前没用过zip,你能解释一下它在这里做什么吗?我只是简单地使用了列表理解,我不知道你可以在列表理解中进行列表理解。不过,对mxx的“外部”列表理解让我有点困惑。此外,v if v else'x'是否会自动检查大于0的整数?它怎么知道用“x”替换什么呢?当然,我会编辑我的帖子,把它逐行分解。哇,非常感谢你的解释。我将不得不修改代码,以便更好地理解视觉效果。如果“上面”为零,“列”中的所有值都将更改为“x”,那么如何修改该代码以包括这样一个场景?例如,下面的示例:[[1,1,1,0],[0,5,0,1],[2,1,3,10]]。您上面的解决方案将第二个列表中的第三个索引更改为“x”,但将列表3中的第三个索引保留为10。@cexcelc I使用底部的一个段落更新了答案,并修改了代码以处理该情况。我最初误解了你的问题,认为你的问题是在
0
s正下方的元素上标记了
“X”
s。
[v1 if v2 else 'x' for v1, v2 in zip(row1, row2)]
def solver(matrix):
    return [[v if all(col) else 'x' for v, col in zip(row, zip(*matrix[:idx]))] for idx, row in enumerate(matrix, 1)]