Earlier today I found this post by Ryan Westlund:
It reminded me that in Python you add a reference to a list to itself, like this:
>>> my_list =  >>> my_list.append(my_list) >>> my_list [1, [...]] >>> my_list [1,[...]] >>> my_list [1, [...]]
Sidenote: this is one of the cases where reference counting breaks down and why Python needs a garbage collector (GC). It is the GCs job is to clean up circular references like these. Now, back to the story!
Here we have recursion and in Python, we have a maximum recursion limit. If you have ever forgotten the base case in a recursive function you probably have seen this error:
RecursionError: maximum recursion depth exceeded during compilation
which is triggered when the limit is reached.
How does accessing the elements work? You can give your own classes the -operator by implementing
__getitem__(self, key). So we can probably think about doing this
my_list as recursive calls to
list.__getitem__( list.__getitem__(my_list, 1), 1 )
It, therefore, seems reasonable that this would trigger the max recursion error if repeated enough times. What is the default maximum recursion limits?
>>> import sys >>> sys.getrecursionlimit() 1000
Wow, that is more than the times I am willing to write  to test my hypothesis. Luckily for us, or at least for me, we can change the recursion limit to let's say 5 using
>>> sys.setrecursionlimit(5) >>> my_list [1, [...]]
It must be an off by one error, let's do 6 access instead.
>>> my_list [1, [...]]
>>> my_list RecursionError: maximum recursion depth exceeded during compilation
Success!!! So, I found 14 access is what is needed for the maximum recursion error to trigger. Interestingly, I only needed 8 when using exec:
>>> exec("my_list" + ""*8) RecursionError: maximum recursion depth exceeded during compilation
I'm actually still not sure what causes this behavior. It is demonstrably true that accessing the elements can cause a RecursionError, however, I do not understand why it took 14 access with a recursion limit of 5. Might it be some sort of optimization going on here? Even more interesting is that using exec takes 8 accesses, more than the limit but less than the other method. If you have any idea on what might be causing the behavior, please leave a comment below. It would be really interesting to hear your thoughts on this one!