Динамический многомерный список в Python

Я хочу создать функцию, которая может вставить заданное значение в заданный индекс в заданный массив. Это довольно просто с двумерными массивами:

def insertInto(index, array, value):
    are index in array?
        no:
            iterate over range (len(array) -> index):
                insert None into array
    insert value into array
    return array

Но что, если я хочу проделать тот же трюк с многомерным индексом?

Предположим, у нас есть arr = [] в начале. Тогда после выполнения insertInto((0,0,2), arr, 'yey') данный arr должен выглядеть как [[[None, None, 'yey']]], так и arr[0][0][2] == 'yey'.

Я пытался сделать такую ​​функцию, но трудно перейти на новый уровень размерности. Моя идея была:

def insertInto(index: tuple, array, value):
    currentCoordinate = index.pop(0)
    currentLevel = array[currentCoordinate]
    while index:  # while len(index) > 0
        if size(array[i]) < currentCoordinate:
            currentLevel = enlargeList(currentLevel, currentCoordinate)
            # enlargeList function enlarge the given list, so it will
            # have required index. the gaps will be filled with None
            # example: enlargeList([1], 3) == [1, None, None, None]
        currentLevel[currentCoordinate] = []
        currentLevel = currentLevel[currentCoordinate]
        # in the next iteration currentLevel variable will be equal to
        # inserted list
        currenCoordinate = index.pop(0)

Проблема с этим решением очень очевидна: я не могу назначить (например) a = l[0] (где l — список, а a — некоторая временная переменная), а затем изменить a, потому что это не повлияет на l (см. этот вопрос).

Кто-нибудь знает, как это сделать по-другому?

Этот код не должен требовать никаких библиотек.

Просто совет. Вместо того, чтобы делать это вручную, есть много способов сделать это с помощью numpy или pandas.

Praveenkumar 18.05.2019 14:48

Хорошо, я уточню, что я все равно хочу сделать это вручную.

Paul Lynn 18.05.2019 14:49

«Я не могу назначить a = l[0], а затем изменить a, потому что это не повлияет на l» — что вы хотите этим сказать? Конечно, если l = [[]]; a = l[0]; a.append(1), то l == [[1]].

mkrieger1 18.05.2019 14:52

И к какой части вашего кода это относится? Что соответствует a и l?

mkrieger1 18.05.2019 14:53

@ mkrieger1, это просто пример. l — случайный список, а a — временная переменная. Я добавлю это к вопросу.

Paul Lynn 18.05.2019 15:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
401
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Способ упростить проблему — использовать рекурсивные функции. Таким образом, переменные остаются в области видимости и не должны стирать друг друга.

Я использовал (index, *tail) вместо индекса на основе кортежа для простоты.

def ensure_array_index(array, index):
    while len(array) <= index:
        array.append(None)
    if array[index] is None:
        array[index] = []

def insert_into(array, value, index, *tail):
    ensure_array_index(array, index)
    if len(tail) == 0:
        array[index] = value
    else:
        insert_into(array[index], value, *tail)


arr = []
insert_into(arr, '001', 0, 0, 1)
insert_into(arr, '011', 0, 1, 1)
insert_into(arr, '211', 2, 1, 1)
insert_into(arr, '1', 1)
print arr

>>> [[[None, '001'], [None, '011']], '1', [None, [None, '211']]]

Единственным недостатком является то, что вы ограничены стеком вызовов python для глубины, которую вы можете вставить (~ 100 afaik)

О, спасибо, это работает просто идеально. Мне также нравится, как вы использовали *tail и index. Какая-то незнакомая мне техника.

Paul Lynn 18.05.2019 15:22

Другие вопросы по теме