Преобразование входных данных в многомерный массив

Рейтинг: 1Ответов: 3Опубликовано: 14.03.2023

Можно ли как-нибудь по-простому строку наподобие

1 1
1 1
1 1
1 1

Преобразовать в трехмерный массив без кучи вложенных циклов?
Вопрос стоит так: каким образом можно строку преобразовать в многомерный массив, зная его (массива) размерность (в примере размерность 2х2х2).

Ответы

▲ 2Принят

Решение без кучи вложенных циклов. Правда рекурсивное.

def fold(shape, seq):
    it = iter(seq)

    def fold(i):
        if i == len(shape):
            return next(it)
        return [fold(i + 1) for _ in range(shape[i])]

    return fold(0)


print(fold((2, 3, 4), range(1, 1 + 2 * 3 * 4)))
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]

Что можно отформатировать в

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

Чтение из строки:

data = '''
1 1
1 1
1 1
1 1
'''
print(fold((2, 2, 2), map(int, data.split())))
[[[1, 1], [1, 1]], [[1, 1], [1, 1]]]

Чтение из входного потока:

def ints():
    while True:
        yield from map(int, input().split())


print(fold((2, 2, 2), ints()))
$ python fold.py
1 1
1 1
1 1
1 1
[[[1, 1], [1, 1]], [[1, 1], [1, 1]]]
▲ 2

Да в общем-то ничего сложного, если использовать Numpy для решейпа:

import numpy as np

data_str = """
1 1
1 1
1 1
1 1
"""

shape = (2, 2, 2)

data = list(map(int, (x for line in data_str.split('\n') for x in line.split())))
arr = np.array(data).reshape(shape)
print(arr)

Вывод:

[[[1 1]
  [1 1]]

 [[1 1]
  [1 1]]]
▲ 2
import numpy as np


s  = """1 1
1 1
1 1
1 1"""

arr = np.fromiter(s.replace("\n", " ").split(), dtype=np.int32)
arr = arr.reshape((2, 2, 2))

print(arr)