Home > OS >  How to nest python lists recursively?
How to nest python lists recursively?

Time:07-20

list0 = [[]]
list0[0].append([])
list0[0][0].append([])
list0[0][0][0].append(["I'm in deep!"])
print(list0)

How do I achieve the nested effect above in a loop? Like how I can append lists to a list in a loop.

def list_deepener(layers):
    list1 = [[]]
    count = 0
    while count != layers:
        count  = 1
        y = "list1"   ("[0]" * count)
        y.append([])
        print(x)
list_deepener(5)

I tried this but I couldn't think of any way to convert the string into code which would allow me to alter list1.

CodePudding user response:

Suppose that we have mylist = [] to begin with, and we want to add lists to a certain depth. The trick is to use a separate variable to keep track of where we are in the nesting process, and update that variable as we add each layer. Thus:

>>> mylist = []
>>> current = mylist
>>> for i in range(5):
...     to_add = []
...     current.append(to_add)
...     current = to_add
... 
>>> mylist # 6 pairs of brackets: the initial list, plus 5 added nested lists
[[[[[[]]]]]]

CodePudding user response:

There's many ways to solve this issue, but when you find yourself constructing code in strings and looking for ways to execute that, you're on the wrong path.

A recursive solution:

def nest(x, levels):
    assert levels >= 0
    if levels == 0:
        return [x]
    else:
        return [nest(x, levels-1)]


print(nest("I'm in deep", 5))

An iterative solution:

def nest(x, levels):
    assert levels >= 0
    result = [x]
    for _ in range(levels):
        result = [result]
    return result


print(nest("I'm in deep", 5))

CodePudding user response:

Another way to think about this is recursively. Consider what you want in the deepest part of your list (your 'base' case') and then layer on top for each iteration.

def deepen(layers: int) -> list:
    if layers <= 1:  # Base case, i.e. 'what happens at the bottom'
        return ["Deeper than deep"]
    else:  # Iterative case, i.e. 'what happens at each layer'
        return [deepen(layers - 1)]

This gives you the correct result:

>>> def deepen(layers: int) -> list:
...     if layers <= 1:
...         return ["Deeper than deep"]
...     else:
...         return [deepen(layers - 1)]
...
>>> deepen(5)
[[[[['Deeper than deep']]]]]

CodePudding user response:

You could pass a range and initial string to functools.reduce for a simple one-liner:

from functools import reduce

layers = 4

reduce(lambda a, _: [a], range(layers), "I'm in deep!")
# [[[["I'm in deep!"]]]]
  • Related