Преобразовать кортеж в индекс для вложенного списка - PullRequest
2 голосов
/ 10 марта 2020

Мне даны координаты для вложенных n-мерных списков, в которые я должен вставить определенное значение.

Что-то вроде (3,1,4) для 3-D списка или (3,1,4,1) для 4-D списка. Правильный способ изменить это значение:

mylist[3][1][4] = 'x'    
mylist[3][1][4][1]  = 'y'

Это легко сделать, если я всегда знаю, сколько измерений в списке, но я должен сделать это для любого n. Мне также не разрешено импортировать что-либо (лабораторное задание). Спасибо!

Ответы [ 3 ]

2 голосов
/ 10 марта 2020

Назначение наподобие mylist[3][1][4] = 'x' - это действительно скрытая цепочка вызовов методов.

mylist.__getitem__(3).__getitem__(1).__setitem__(4, 'x')

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

idx = (3, 1, 4)

t = mylist
*dig, update = idx
for i in dig:  # (3, 1) are used for __getitem__
    t = t[i]
# t == mylist[3][1]
# t[4] = 'x' == t.__setitem__(4, 'x')
t[update] = 'x'
2 голосов
/ 10 марта 2020

Этот mylist[3][1][4][1] = thing такой же, как этот:

tmp = mylist[3][1][4]
tmp[1] = thing

Вы можете использовать этот факт следующим образом:

def setitem(the_list, indices: tuple, value):
    try:
        index, = indices
    except ValueError:
        # there's more than one index - dig one dimension deeper
        setitem(the_list[indices[0]], indices[1:], value)
    else:
        # one index left - use it in assignment
        the_list[index] = value

Затем позвоните:

mylist[3][1][4][1]  = 'y'
setitem(mylist, (3, 1, 4, 1), 'y')
0 голосов
/ 10 марта 2020

вы можете использовать рекурсивный подход:

def change_item(nested_list, indices, value):
    if len(indices) > 1:
        change_item(nested_list[indices[0]], indices[1:])

    else:
        nested_list[indices[0]] = value

change_item(mylist, (3,1,4), 'x')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...