Search code examples
pythonrecursionnested-lists

Modify a nested list recursively in Python


I have a nested list of string / list(str) like:

li = [["1", ["2", "3"]], "4", [[["5", "6", "7"], "10", "11"], ["12", "13", "14"]]]

I want as output a list with the same nested structure, but all the sublists that satisfy the conditions:

  • len(sublist) in {2, 3}
  • all elements in list are <str> (see the function to_true)

must be replaced with a True. The expected output should be

[["1", True], "4", [[True, "10", "11"], True]]

How can I write a function that (possibly recursively) does it?
Another possible way is also modifying inplace the input list after a deepcopy.

def to_true(o) -> bool:
    # True if o is a 2/3 element list/tuple containing only <str>
    if not isinstance(o, (list, tuple)):
        return False

    if len(o) not in {2, 3}:
        return False

    return all(isinstance(i, str) for i in o)

>>> func(li)

[["1", True], "4", [[True, "10", "11"], True]]


Solution

  • Try that:

    def my_func(my_list):
        result = []
        for i in my_list:
            if isinstance(i, list):
                # Recursively transform the sublist
                result.append(my_func(i))
            else:
                result.append(i)
        # Check if the result should be replaced with True
        if all(isinstance(i, str) for i in result) and len(result) in {2, 3}:
            return True
        return result
    
    my_list = [["1", ["2", "3"]], "4", [[["5", "6", "7"], "10", "11"], ["12", "13", "14"]]]
    
    print(my_func(my_list))
    

    output:

    [['1', True], '4', [[True, '10', '11'], True]]