a[-1] refers to the last element of a, in this case a[3]. The for loop is a bit unusual in that it is using this element as the loop variable.
It's not evaluating that element upon loop entry, but rather it is assigning to it on each iteration through the loop.
So first a[-1] gets set to 0, then 1, then 2. Finally, on the last iteration, the for loop retrieves a[3] which at that point is 2, so the list ends up as [0, 1, 2, 2].
A more typical for loop uses a simple local variable name as the loop variable, e.g. for x .... In that case, x is set to the next value upon each iteration. This case is no different, except that a[-1] is set to the next value upon each iteration. You don't see this very often, but it's consistent.