I was just looking at the implementation of functools.lru_cache, when I stumbled across this snippet:
root =  # root of the circular doubly linked list root[:] = [root, root, None, None] # initialize by pointing to self
I am familiar with circular and doubly linked lists. I am also aware that
new_list = my_list[:] creates a copy of my_list. When looking for slice assignments or other implementations of circular doubly linked lists, I could not find any further information on this specific syntax.
- What is going on in this situation.
- Is there a different syntax to achieve the same result?
- Is there a different common use case for
some_list[:] = some_iterable(without the self reference)?
root[:] = [root, root, None, None]
left hand slice assignment just says that the reference of
root is reused to hold the contents of the right part.
root reference never changes, and yes, in a list you can reference yourself (but don't try recursive flattening on those :). The representation displays a "recursion on list" in that case.
>>> root [<Recursion on list with id=48987464>, <Recursion on list with id=48987464>, None, None]
and printing it shows ellipsis:
>>> print(root) [[...], [...], None, None]
note that you don't need slice assignment for this. There are simple ways to trigger a recursion:
>>> root =  >>> root.append(root) >>> root [<Recursion on list with id=51459656>] >>>
append doesn't change reference as we all know, it just mutates the list, adding a reference to itself. Maybe easier to comprehend.