Первая проблема состоит в том, чтобы перебирать список по порядку, независимо от глубины вложения.Вот генератор, который возвращает именно это (вдохновленный этим ответом ):
import functools
import operator
def iter_nested_list(input_list):
# build index of first level elements
index_list_to_check = [(i, ) for i in range(len(input_list))]
while len(index_list_to_check) > 0:
current_index = index_list_to_check.pop(0)
# get the element
elem = functools.reduce(operator.getitem, current_index, input_list)
if isinstance(elem, list):
for i in range(len(elem)):
# this is a list, so we need to check one level deeper
index_list_to_check.append(current_index + (i, ))
else:
# this is not a list, so we yield the index
yield current_index
Это можно использовать так:
>>> list_1 = [[2,233],[[[4,5],[66.33]],[[24,88.65,103,2200.0],[-44.2,-8,5]]],[[[[[[[[5]]]]]]]]]
>>> iter_nested_list(list_1)
<generator object iter_nested_list at 0x7fdbbc29d990>
>>> list(iter_nested_list(list_1))
[(0, 0), (0, 1), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 0, 2), (1, 1, 0, 3), (1, 1, 1, 0), (1, 1, 1, 1), (1, 1, 1, 2), (2, 0, 0, 0, 0, 0, 0, 0, 0)]
Чтобы получить одинЭлемент из списка, мы можем использовать полученные индексы:
>>> index_list = list(iter_nested_list(list_1))
>>> index = index_list[1]
>>> index
(0, 1)
>>> functools.reduce(operator.getitem, index, input_list)
233
Теперь, чтобы изменить элемент:
def modify(input_list, value_to_add):
index_list = list(iter_nested_list(list_1))
index = random.choice(index_list)
index_base = index[:-1] # list of all elements from 'index' excluding the last one
index_elem = index[-1] # single element, the last of the list 'index'
# get list that holds the value we randomly selected
sub_list = functools.reduce(operator.getitem, index_base, input_list)
# modify value
sub_list[index_elem] += value_to_add
И вот он в действии:
>>> list_1 = [[2,233],[[[4,5],[66.33]],[[24,88.65,103,2200.0],[-44.2,-8,5]]],[[[[[[[[5]]]]]]]]]
>>> modify(list_1, 5)
>>> list_1
[[2, 233], [[[4, 5], [66.33]], [[24, 88.65, 103, 2200.0], [-44.2, -8, 10]]], [[[[[[[[5]]]]]]]]]
>>> modify(list_1, 5)
>>> list_1
[[2, 233], [[[4, 5], [66.33]], [[24, 88.65, 103, 2205.0], [-44.2, -8, 10]]], [[[[[[[[5]]]]]]]]]
>>> modify(list_1, 5)
>>> list_1
[[2, 233], [[[4, 5], [66.33]], [[24, 88.65, 103, 2205.0], [-39.2, -8, 10]]], [[[[[[[[5]]]]]]]]]