Iterating through nested lists


hi all,

I’m starting to try and learn python and I was hoping someone could explain the logic of how the function below works or rather how it iterates through a nested list…

a = IN[0]

def square(item):
if isinstance(item, list):
    return [square(x) for x in item]
    return item * item
x = []

x = square(a)

# Assign your output to the OUT variable.
OUT = x

In particular the line after isinstance.

I know isinstance(item, list) will return true if the item is a list but how does it actually perform the function on the list i.e. how does it get to the ‘else’ part of the if statement?

Any explaination gratefully received.




My explanation might be a little poorly written so if you have any questions please ask.

The naming in that script is a bit confusing since you have x as both a global variable in the script and a local variable in the function. That aside, that square(item) function is a recursive function, meaning it will keep calling itself if the item is a list, until the item is not a list, then it will do what is in the else section.

What is key to the recursive part is in the return section of isinstance, return [square(x) for x in item], so if the input is a list, you will run square() for each item in that list. The idea is that if the input is a list, then (in Dynamo terms) run the program one list level deeper in that list, until you eventually get something that is not a list.

So let’s say IN[0] is a list like [[1,2,3],[4,5,6]], two nested lists.

When you call the square function, it will take the whole IN[0], this case it is square([[1,2,3],[4,5,6]]) and check, is [[1,2,3],[4,5,6]] a list? Yes, so it will call itself again but this time for each item inside that list, which are [1,2,3] and [4,5,6].

So now we are calling square([1,2,3]). Once again, it will check if [1,2,3] is a list and yes it is. Then we will call square again but for each item in the [1,2,3] list.

This iteration is now square(1). Is 1 a list? No, so it will do the else statement, return item * item, which is return 1 * 1 or return 1.

It will do the same for the rest of the [1,2,3] list and return 1, 4, and 9. Then we go back and perform the square function on the next list up, [4,5,6] and in the same way we will get 16, 25, and 36.

At the end, it will return all of the squares of each individual item as the list and you should end up with [[1, 4, 9], [16, 25, 36]]


@kennyb6 thanks for the quick reply! that makes sense at least it makes sense when I read it. the test will be if I can apply the same logic to a new script!!

Good point on the use of x as a variable - something I definitely need to tighten up on and best do it now before I get too far into this stuff!!

Thanks again.