对角列出嵌套列表中的元素

时间:2014-04-14 20:09:38

标签: python python-3.x

这是我的第一篇文章,我是一个非常新的这个很棒的网站。

我希望对角列出3x3阵列中的所有元素:

L = [  [1, 2, 3],
       [4, 5, 6],
       [7, 8, 9] ]

预期产出:

[[7], [4, 8], [1, 5, 9], [2, 6], [3]]

另外,我如何将它推广到任何N x N数组?

编辑:我之前已经注意到了这个问题,但是我正在寻找一种不用导入numpy或任何库的方法。

Edit2:我的一个同学提供了这个解决方案,我最喜欢它:

由于你从左下角开始找到对角线,你可以通过从方块的右上角开始并最后反转你的解决方案来做到这一点。我的方法是首先反转L中的每一行,然后将每个元素附加到其对应的对角线列表中。这里的见解是你开始在每一行中追加元素K而不是在最终列表的第一个子列表中,但是从indice K开始。例如在将行[4,5,6]反转到行[6,5之后4],我会将6添加到我的对角排序列表的第二个子列表中(因为这是第2行),然后我将5添加到第3个子列表,然后我将4添加到第4个子列表。但是,如果我在对角线列表中没有第四个子列表,我会添加第四个空列表,然后用4填充。

我的解释可能不太清楚,所以这里是我的代码。

def diagonal(l):

    L = l[:]
    return_list = [[] for i in range(len(L))]

    for line in range(len(L)):
        L[line].reverse()
        i = line

        for elem in L[line]:
            if i >= len(return_list):
                return_list.append([])

            return_list[i].append(elem)
            i += 1

    return_list.reverse()
    return return_list

1 个答案:

答案 0 :(得分:9)

仅使用Python(无NumPy):

import itertools as IT

L = [  [1, 2, 3],
       [4, 5, 6],
       [7, 8, 9] ]
N = len(L)
d = dict()
for i,j in IT.product(range(N), repeat=2):
    d.setdefault(j-i, []).append((i,j))

print([[L[i][j] for i,j in d[k]] for k in range(-N+1, N)])    
# [[7], [4, 8], [1, 5, 9], [2, 6], [3]]

或者,更好的是,使用Nemo's transformation(推广到h x w形状的矩阵:

L = [  [1, 2, 3,],
       [4, 5, 6,],
       [7, 8, 9,], ]

h, w = len(L), len(L[0])

print([[L[h-1-q][p-q]
        for q in range(min(p, h-1), max(0, p-w+1)-1, -1)]
       for p in range(h+w-1)])                             
# [[7], [4, 8], [1, 5, 9], [2, 6], [3]]

我们还可以将此代码放在函数中以便于使用:

def diagonals(L):
    """
    https://stackoverflow.com/a/31373955/190597 (unutbu)
    >>> L = array([[ 0,  1,  2],
                   [ 3,  4,  5],
                   [ 6,  7,  8],
                   [ 9, 10, 11]])

    >>> diagonals(L)
    [[9], [6, 10], [3, 7, 11], [0, 4, 8], [1, 5], [2]]
    """
    h, w = len(L), len(L[0])
    return [[L[h - p + q - 1][q]
             for q in range(max(p-h+1, 0), min(p+1, w))]
            for p in range(h + w - 1)]


def antidiagonals(L):
    """
    >>> L = array([[ 0,  1,  2],
                   [ 3,  4,  5],
                   [ 6,  7,  8],
                   [ 9, 10, 11]])

    >>> antidiagonals(L)
    [[0], [3, 1], [6, 4, 2], [9, 7, 5], [10, 8], [11]]
    """
    h, w = len(L), len(L[0])
    return [[L[p - q][q]
             for q in range(max(p-h+1,0), min(p+1, w))]
            for p in range(h + w - 1)]