Как изменить содержимое вложенного списка? - PullRequest
0 голосов
/ 03 июня 2019

У меня есть несколько вложенных списков, и я хочу иметь возможность изменять их, имея индексы, где будет происходить изменение.

Один из примеров таких списков:

l2 = ['Node_50',
      ['Node_48', 'Node_23', ['Node_12', 'Node_3'], ['Node_20']],
      ['Node_22', ['Node_44'], ['Node_7', 'Node_40']]
     ]

У меня теперь есть новый список элементов и список с индексами

lnew = ['Node_1', 'Node_40', 'Node_17']
indexes = [1, 3]

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

l2[1][3] = lnew

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

Ответы [ 3 ]

2 голосов
/ 03 июня 2019

короче:

l2 = ['Node_50',
      ['Node_48', 'Node_23', ['Node_12', 'Node_3'], ['Node_20']],
      ['Node_22', ['Node_44'], ['Node_7', 'Node_40']]
     ]


lnew = ['Node_1', 'Node_40', 'Node_17']
indexes = [1, 3]


def set_deep(root, indexes, value):

    for x in indexes[:-1]:
        root = root[x]
    root[indexes[-1]] = value


set_deep(l2, indexes, lnew)


print(l2)

Подумав об этом, список возможностей [iterable] должен быть добавлен в Python.Я думаю, что на самом деле numpy поддерживает нотацию list [list]?

2 голосов
/ 03 июня 2019

Я думаю, что user8426627 уже дал отличный ответ, но если вы предпочитаете функциональный стиль, вы можете сделать что-то вроде этого:

>>> from functools import reduce
>>> from operator import getitem
>>> reduce(getitem, indexes[:-1], l2)[indexes[-1]] = lnew
>>> l2
['Node_50',
  ['Node_48', 'Node_23', ['Node_12', 'Node_3'], ['Node_1', 'Node_40', 'Node_17']],
  ['Node_22', ['Node_44'], ['Node_7', 'Node_40']]]
0 голосов
/ 03 июня 2019

Вам не нужна функция, просто присвойте новый список желаемой позиции, и он заменит предыдущее значение.

l2 = ['Node_50',
       ['Node_48', 'Node_23', ['Node_12', 'Node_3'], ['Node_20']],
       ['Node_22', ['Node_44'], ['Node_7', 'Node_40']]
      ]
lnew = ['Node_1', 'Node_40', 'Node_17']

до

l2[1][3]

возвращает

['Node_20']

затем замените его

l2[1][3] = lnew

после

l2[1][3]

возвращает

['Node_1', 'Node_40', 'Node_17']

Это также можно сделать с помощью функции

def myFUN(LIST, newLIST, indexes):
    i,j = indexes
    if i >= len(LIST):
        print("list index (" + str(i) + ") out of range")
        return
    elif j >= len(LIST[i]):
        print("list index (" + str(j) + ") out of range")
        return
    else:
        LIST[i][j] = newLIST
        return LIST

сейчас

myFUN(l2, lnew, indexes)

возвращает

['Node_50', ['Node_48', 'Node_23', ['Node_12', 'Node_3'], ['Node_1', 'Node_40', 'Node_17']], ['Node_22', ['Node_44'], ['Node_7', 'Node_40']]]

, но

myFUN(l2, lnew, (4,1))

возвращает

list index (4) out of range

и

myFUN(l2, lnew, (1,25))

возвращает

list index (25) out of range

Сохранить исходный список без изменений

Для python3

def myFUN(LIST, newLIST, indexes):
    res = LIST.copy()
    i,j = indexes
    if i >= len(LIST):
        print("list index (" + str(i) + ") out of range")
        return
    elif j >= len(LIST[i]):
        print("list index (" + str(j) + ") out of range")
        return
    else:
        res[i][j] = newLIST
        return res

inPython 2 использовать res = LIST[:] или res=list(LIST).Теперь

myFUN(l2, lnew, indexes)

возвращает

['Node_50', ['Node_48', 'Node_23', ['Node_12', 'Node_3'], ['Node_1', 'Node_40', 'Node_17']], ['Node_22', ['Node_44'], ['Node_7', 'Node_40']]]

, но l2 остается неизменным

l2

возвращает

['Node_50', ['Node_48', 'Node_23', ['Node_12', 'Node_3'], ['Node_20']], ['Node_22', ['Node_44'], ['Node_7', 'Node_40']]]
...