【问题标题】:What is the pythonic solution to enumerate and update items from a matrix?从矩阵中枚举和更新项目的pythonic解决方案是什么?
【发布时间】:2019-10-13 22:58:22
【问题描述】:

我使用 enumerate 从矩阵中的值执行了一个 for 循环,并尝试将值分配给不同于 0 的项目,同时附加到等于 0 的列表元素。事实是原始矩阵不'不会更新。

示例代码:

matrix = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]
current = []
for x, i in enumerate(matrix):
    for y, j in enumerate(i):
        if j == 0:
            current.append((x, y))
        else:
            #matrix[x][y] = -1 # This works
            j = -1 # This doesn't

由于这不起作用,因此在这种情况下使用 enumerate 没有任何实用性。于是我把代码改成了:

matrix = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]
current = []
for x in range(len(matrix)):
    for y in range(len(matrix[0])):
        if matrix[x][y] == 0:
            current.append((x, y))
        else:
            matrix[x][y] = -1

IMO 上面的代码可读性差很多,而且 pylint 建议不要将其用于:

C0200:考虑使用枚举而不是使用范围和迭代 len(考虑使用枚举)

【问题讨论】:

  • 您在尝试累积新列表的同时还更改原始列表这一事实将限制这有多好。我会在这里使用列表理解/生成器表达式,但这需要一些额外的迭代。性能有多重要?
  • @Carcigenicate 我有一个约束,我只需要查看矩阵中的项目一次。
  • 我认为您可能会坚持使用第二种解决方案。不是每个问题都有一个漂亮的解决方案。 Linter 警告是很好的建议,而不是硬性规则。

标签: python-3.x matrix pylint enumerate


【解决方案1】:

您不能通过分配给局部变量 j = -1(在每次循环迭代时重新初始化 for y, j in enumerate(i))来就地更新二维数组。

在您的简单情况下,您可以使用以下简单遍历更新您的 矩阵

matrix = [[0, 0, 0], [0, 1, 0], [1, 1, 1]]
for i, row in enumerate(matrix):
    for j, val in enumerate(row):
        if val != 0: matrix[i][j] = -1

print(matrix)    # [[0, 0, 0], [0, -1, 0], [-1, -1, -1]]

虽然 Numpy 提供了一种更强大的矩阵更新方式:

import numpy as np

matrix = np.array([[0, 0, 0], [0, 1, 0], [1, 1, 1]])
matrix = np.where(matrix == 0, matrix, -1)

print(matrix)

【讨论】:

  • 是的,这正是我在我的例子中的表达方式。请参阅:#matrix[x][y] = -1 # This works。但是为什么j = -1 不起作用?没有更清洁的解决方案吗?
  • 还要注意我需要同时更新current列表。
  • @StaticX j = -1 不起作用,因为 j 只是一个局部变量。 j = -1 只是更改 j 指向的内容。如果你有x = 1; y = x; x = 2;y 仍然等于1
  • @StaticX,如前所述,您正在尝试通过局部变量 j = -1 就地更新二维数组 - 这是完全错误的
猜你喜欢
  • 1970-01-01
  • 2020-04-09
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 2021-07-07
相关资源
最近更新 更多