对角地列出嵌套列表中的元素 [英] listing elements in a nested lists diagonally

查看:30
本文介绍了对角地列出嵌套列表中的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一篇文章,我是这个很棒的网站的新手.

this is my first post, i'm pretty new this awesome site.

我想对角地列出 3x3 数组中的所有元素:

i'd like to list all elements in a 3x3 array diagonally:

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

预期输出:

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

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

Also, how would I generalize it to any N x N array?

我注意到之前有人问过这个问题,但我正在寻找一种不导入 numpy 或任何库的方法.

I've noticed this has been asked before yet i'm looking for a way without importing numpy or any library for that matter.

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

One of my classmates offered this solution, I like it the most:

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

Since you finding diagonals starting from the bottom left corner, you could do this by starting in the top right corner of the square and reversing your solution in the end. My approach was first reversing each row in L, and then appending each element to its corresponding diagonal list. The insight here is that you start appending elements in each row K not in the first sub-list of the final list, but starting at indice K. For instance after reversing row [4,5,6] to row [6,5,4], I would append 6 to the 2nd sublist of my diagonally ordered list (since this is the 2nd row), then I would append 5 to the 3rd sublist, and then I would append 4 to the fourth sublist. However, if I didn't have a fourth sublist at the moment in time in my diagonal list, I would add a fourth empty list, then fill it with 4.

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

My explanation may not be too clear, so here's the code I have.

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

推荐答案

只使用 Python(不使用 NumPy):

Using only Python (no 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 的变换(推广到 hxw 形状的矩阵:


Or, even better, use Nemo's transformation (generalized to h x w shaped matrices:

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]]

<小时>

我们也可以将这段代码放在一个函数中以便于使用:


We can also put this code in a function for easier usage:

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)]

这篇关于对角地列出嵌套列表中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆