Я хочу создать функцию, которая может вставить заданное значение в заданный индекс в заданный массив. Это довольно просто с двумерными массивами:
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 (см. этот вопрос).
Кто-нибудь знает, как это сделать по-другому?
Этот код не должен требовать никаких библиотек.
Хорошо, я уточню, что я все равно хочу сделать это вручную.
«Я не могу назначить a = l[0], а затем изменить a, потому что это не повлияет на l» — что вы хотите этим сказать? Конечно, если l = [[]]; a = l[0]; a.append(1), то l == [[1]].
И к какой части вашего кода это относится? Что соответствует a и l?
@ mkrieger1, это просто пример. l — случайный список, а a — временная переменная. Я добавлю это к вопросу.






Способ упростить проблему — использовать рекурсивные функции. Таким образом, переменные остаются в области видимости и не должны стирать друг друга.
Я использовал (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. Какая-то незнакомая мне техника.
Просто совет. Вместо того, чтобы делать это вручную, есть много способов сделать это с помощью
numpyилиpandas.