Python variables know their types based on the type of variable assigned to it. It is a dynamically typed language. In your code, the interpreter sees foo1 = foo1[0] = [0] and it finds a value at the end, which is [0]. It is a list with one element 0. Now, this gets assigned to the first element of the list foo1 through foo1[0] = [0]. But since foo1 is already declared, it creates an object which has a pointer to itself, and hence foo1 gets self-referenced infinitely, with the innermost list having 0.
The structure of the list foo1 will be the same when the code is foo1 = foo1[0].
The object foo1 has entered an infinite self-referenced loop.