如何多次移动二维数组的列,同时仍考虑其原始位置?

Posted

技术标签:

【中文标题】如何多次移动二维数组的列,同时仍考虑其原始位置?【英文标题】:How to shift the columns of a 2D array multiple times, while still considering its original position? 【发布时间】:2017-08-22 04:15:48 【问题描述】:

好吧,假设我有一个矩阵m,如下:

m = [[0, 1, 0, 0, 0, 1],
     [4, 0, 0, 3, 2, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0]]

我的目标是检查矩阵的每一行,看看该行的总和是否为零。如果总和不为零,我想将该行对应的列移动到矩阵的末尾。如果行的总和为零,则不会发生任何事情。所以在上面的给定矩阵中应该出现以下情况:

    程序发现第 0 行的和不等于 0

    矩阵的第0列移到矩阵的末尾,如下:

    m = [[1, 0, 0, 0, 1, 0],
         [0, 0, 3, 2, 0, 4],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0]]
    

    程序检查下一行并做同样的事情,将列移动到矩阵的末尾

    m = [[0, 0, 0, 1, 0, 1],
         [0, 3, 2, 0, 4, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0]]
    

    检查其他每一行,但由于它们的和都为零,因此不进行移位,最终结果是上面的矩阵。

第一次移动矩阵的列后会出现问题,一旦所有值都被移动,就很难判断哪一列对应于正确的行。

我不能使用numpy 来解决这个问题,因为我只能使用原始的 Python 2 库。

【问题讨论】:

【参考方案1】:

使用一个简单的循环,当总和不等于零时,再次循环遍历行并将弹出的第一项附加到每一行。

>>> from pprint import pprint
>>> m = [[0, 1, 0, 0, 0, 1],
    [4, 0, 0, 3, 2, 0],
    [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0]]
>>> for row in m:
    # If all numbers are >= 0 then we can short-circuit this using `if any(row):`.
    if sum(row) != 0:
        for row in m:
            row.append(row.pop(0))
...
>>> pprint(m)
[[0, 0, 0, 1, 0, 1],
 [0, 3, 2, 0, 4, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0]]

list.pop 是 O(N) operation,如果您需要快速的东西,请使用 collections.deque

【讨论】:

很好,这真是太棒了。 谢谢。我不知道如此明显的解决方案是如何逃脱了我的。正如您可能会说的那样,我仍然是一个新手程序员。特别感谢您这么快回答(4 分钟,哇!) 使用deque的时间差不多了。 @stamaimer 转换为双端队列可能会减慢速度。如果我们从 deque 本身开始,那么它应该会更快。虽然对于小列表,它几乎不会被注意到。【参考方案2】:

deque 可以旋转元素。

from collections import deque

def rotate(matrix):

    matrix_d = [deque(row) for row in matrix]

    for row in matrix:

        if sum(row) != 0:

            for row_d in matrix_d:

                row_d.rotate(-1)

    return [list(row) for row in matrix_d]

【讨论】:

有趣,我会研究一下。

以上是关于如何多次移动二维数组的列,同时仍考虑其原始位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何对二维数组的列进行排序?

了解如何从内部函数更新原始二维数组

将 byte[] 转换为原始二维数组

如何模糊点的 3D 数组,同时保持其原始值? (Python)

访问大型 numpy 数组,同时保留其顺序

c++输入一个5行5列的二维数组,求最大值和最小值其对应行列的位置。。