Динамический многомерный список в Python - PullRequest
0 голосов
/ 18 мая 2019

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

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 (см. этот вопрос ).

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

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

1 Ответ

1 голос
/ 18 мая 2019

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

Я использовал (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)

...