Управление каждым элементом n-уровневого глубокого списка списков в python - PullRequest
0 голосов
/ 06 августа 2020

Предположим, у нас есть список списков:

list_of_lists = [['a','b'],['x','y','z']]

Что можно считать эффективным способом присвоения значения каждому элементу?

new_list_of_lists = assign_value_to_all_elements(list_of_lists,'0') 
print(new_list_of_lists) 
>> [['0','0'],['0','0','0']]

Неэффективный способ, который приходит мне в голову:

def assign_value_to_all_elements(list_of_lists, new_value = '0'):
    for i in range(len(list_of_lists)):
        for j in range(len(list_of_lists[i])):
            list_of_lists[i][j] = new_value
    return list_of_lists

Мы даже не можем сделать это с массивом numpy:

import numpy as np
list_of_lists_as_np_array = np.array([['a','b'],['x','y','z']])
list_of_lists_as_np_array[:,:] = '0'
Traceback (most recent call last):
  File "<ipython-input-17-90ee38fde5f2>", line 3, in <module>
    list_of_lists_as_np_array[:,:] = '0'
IndexError: too many indices for array

Только когда оба списка одинаковы size, это работает:

import numpy as np
   ...: list_of_lists_as_np_array = np.array([['a','b'],['x','y']])
   ...: list_of_lists_as_np_array[:,:] = '0'
   ...: list_of_lists_as_np_array
Out[23]: 
array([['0', '0'],
       ['0', '0']], dtype='<U1')

В этом примере мы работаем со списком списков (глубина 2 уровня).

Однако это можно обобщить до списка списка ... списки (n уровней в глубину).

Есть ли общий способ назначать или управлять каждым «базовым элементом» (под которым я подразумеваю type (element)! = list) в n-уровневом глубоком списке списков ?

1 Ответ

1 голос
/ 06 августа 2020

Мы будем использовать здесь рекурсию, поскольку мы не хотим писать n циклы for и все равно не можем этого сделать, так как глубина вашего списка списков заранее не известна.

Уловка для повторного вызова функции, если просматриваемый в данный момент элемент является списком, или заменить его значение на value, если это не так.

def assign_value_to_all_elements(nested_list, value):
    for n, element in enumerate(nested_list):
        if type(element) is list:
            assign_value_to_all_elements(element, value) # Same work but on a smaller
                                                         # segment of the initial list!
        else:
            nested_list[n] = value

l = [['a', 'b'], ['x', 'y', 'z'], [[1, 2, 3, [4, 5, 6]]], [[[[[[[[None]]]]]]]]]
assign_value_to_all_elements(l, 0)
print(l)
>>> [[0, 0], [0, 0, 0], [[0, 0, 0, [0, 0, 0]]], [[[[[[[[0]]]]]]]]]
...