简体   繁体   中英

Manipulating every element in an n-level deep list of lists in python

Assuming we have a list of lists:

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

What could be considered as an efficient way to assign a value for each element?

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

A non-efficient way that comes to my mind is:

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

We even cannot do this with a numpy array:

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

Only when both lists are the same size, it works:

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')

In the example, we are working with list of lists (2 levels deep).

However this could be generalized to list of list of... lists (n levels deep).

Is there a general way to assign to or manipulate every 'base element' (by which i mean type(element)?=list ) in an n-level deep list of lists?

We will use recursion here since we don't want to write n for-loops and cannot do it anyway as the depth of your list of lists is not known in advance.

The trick is to call the function again if the currently viewed element is a list, or replace its value with value if it's not.

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]]]]]]]]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM