Python:如何将2D列表顺时针方向转换为1D列表?

3

我对Python有点新手,正在寻找一个函数,可以将任何n x n二维列表转换为一维列表,并按顺时针方向排列。

例如:

当 n = 3 时

list = [[2, 3, 5],[ 8, 7, 1],[ 0, 4, 6]]

或者

list = [[2, 3, 5]
       ,[8, 7, 1]
       ,[0, 4, 6]]

将会变成

result = [2, 3, 5, 1, 6, 4, 0, 8, 7]

当n = 5时

list = [[2, 3, 5, 9, 10],[ 8, 7, 1, 11, 13],[ 0, 4, 6, 21, 22], [12, 19, 17, 18, 25], [14, 15, 16, 23, 24]]

或者

list = [[  2,  3,  5,  9, 10]
       ,[  8,  7,  1, 11, 13]
       ,[  0,  4,  6, 21, 22]
       ,[ 12, 19, 17, 18, 25]
      , [ 14, 15, 16, 23, 24]]

会变成

result = [2, 3, 5, 9, 10, 13, 22, 25, 24, 23, 16, 15, 14, 12, 0, 8, 7, 1, 11, 21, 18, 17, 19, 4, 6]

我如何才能高效地处理任何值为nxn的情况?

你是在寻找适用于任意nxn列表的东西,还是只有3x3的? - Jack Evans
@JackEvans 对于任何nxn的矩阵 :') - Mohammad Zain Abbas
你能否提供不同大小列表中顺时针旋转的其他示例? - Jack Evans
@JackEvans 我添加了更多细节。你可以看看。 :') - Mohammad Zain Abbas
可能是以螺旋顺序打印二维数组的重复问题。 - Jack Evans
5个回答

1

改编自在螺旋顺序中打印二维数组

import itertools

arr = [[2,  3,  5,  9, 10],
       [8,  7,  1, 11, 13],
       [0,  4,  6, 21, 22],
       [12, 19, 17, 18, 25],
       [14, 15, 16, 23, 24]]


def transpose_and_yield_top(arr):
    while arr:
        yield arr[0]
        arr = list(zip(*arr[1:]))[::-1]


rotated = list(itertools.chain(*transpose_and_yield_top(arr)))

感谢您的赞赏。谢谢您:') - Mohammad Zain Abbas

1
这听起来像是一道考试题目 - 是吗?!
以下是我使用递归和Python列表操作符的解决方案:
def clockwise(input_list, output_list):
    list_size = len(input_list[0])
    if list_size == 1:
        output_list.append(input_list[0][0])
    else:
        for i in range(list_size):
            output_list.append(input_list[0][i])

        for i in range(list_size)[1:]:
            output_list.append(input_list[i][list_size - 1])

        for i in reversed(range(list_size)[:-1]):    
            output_list.append(input_list[list_size - 1][i])

        for i in reversed(range(list_size)[1:-1]):    
            output_list.append(input_list[i][0])

        new_list = list()
        for i in range(list_size - 2):
            new_list.append(input_list[i + 1][1:-1])

        return clockwise(new_list, output_list)

l = [[2, 3, 5, 9, 10],[ 8, 7, 1, 11, 13],[ 0, 4, 6, 21, 22], [12, 19, 17, 18, 25], [14, 15, 16, 23, 24]]
output_list = []
clockwise(l, output_list)

print output_list

1
不,这是我的一个项目需要的东西;我需要它来实现本地二值模式算法。非常感谢您的帮助。:') - Mohammad Zain Abbas

1
这也可以工作:

from math import floor

lists = [[  2,  3,  5,  9, 10]
       ,[  8,  7,  1, 11, 13]
       ,[  0,  4,  6, 21, 22]
       ,[ 12, 19, 17, 18, 25]
      , [ 14, 15, 16, 23, 24]]

n = len(lists) # assume each list also has n-length

output_list = []

idx = 0
while idx <= floor(n/2):

    if len(output_list) == n*n:
        break

    # across ->
    print("Across ->")
    for item in lists[idx][idx:n-idx]:
        output_list.append(item)
    print(output_list)

    if len(output_list) == n*n:
        break

    # down
    print("Down")
    for _idx in range(idx+1, n-idx-1):
        output_list.append(lists[_idx][n-idx-1])
    print(output_list)

    if len(output_list) == n*n:
        break

    # across <-
    print("Across <-")
    for _idx in range(n-idx-1, idx-1, -1):
        output_list.append(lists[n-idx-1][_idx])
    print(output_list)

    if len(output_list) == n*n:
        break

    # up
    print("Up")
    for _idx in range(n-idx-2, idx, -1):
        output_list.append(lists[_idx][idx])
    print(output_list)

    idx += 1


print("\nOutput: ")
print(output_list)

它可以通过几种方式进行清理,但逻辑已经存在。 - J. Darnell
没问题。谢谢你 :') - Mohammad Zain Abbas

1
import math
import numpy as np

def print_wall(input, result):

    n = input.shape[0]

    for i in range(n):  # print top outer
        result.append(input[0][i])

    for i in range(n - 1):  # print right outer
        result.append(input[i + 1][n - 1])

    for i in range(n - 1):  # print bottom outer
        result.append(input[n - 1][n - 2 - i])

    for i in range(n - 2):  # print left outer
        result.append(input[n - 2 - i][0])

def clock_wise(input):

    n = input.shape[0]

    result = list()

    for i in range(math.ceil(n / 2)):  # from the outer to the inner

        print_wall(input[i: n - i, i: n - i], result)

    print(result)

这个方法从数组的外部向内部打印。例如,数组是:
1  2  3  4  5
6  7  8  9  10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

首先,按照顺时针的方向打印5x5数组的外部,得到1 2 3 4 5 10 15 20 25 24 23 22 21 16 11 6;

然后,处理内部的3x3数组:

7  8  9
12 13 14
17 18 19

打印3x3数组的外部,按顺时针方向,得到7 8 9 14 19 18 17 12;

最后,处理13。


0
lists = [[2, 3, 5],[ 8, 7, 1],[ 0, 4, 6]]
output_list = [item for list in lists for item in list]

看,这就是关键所在。你只是将二维列表转换成了一维列表(错过了顺时针转换的重点)。 - Mohammad Zain Abbas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接