The difference lies in how you access the variable, which causes it to be treated differently. Consider this:
def isValid():
top = -1
def push():
print(top)
push()
isValid()
Here there is no error, since top
can be found in the scope of isValid()
and calling push()
will print it correctly. However, if you add top += 1
, Python correctly infers that top
apparently has to be a local variable for that to work, but it isn't, so now top
is showing as problematic everywhere inside push()
(in most IDEs).
def isValid():
top = -1
def push():
print(top) # you'll see error messages / highlighting for top here
top += 1 # and here as well
push()
isValid()
Note that top += 1
isn't even the first statement, but its presence causes print(top)
to no longer work either, since top
now has to be local. But since there's no assignment to top
before the other two statements, Python will correctly complain that it has been accessed before having been assigned.
The reason this doesn't happen with your stack
is that you're not actually trying to change stack
inside push()
. You're trying to change one of its elements (stack[1]
), but that doesn't change what object stack
is naming - you're not assigning to stack
itself, so it does not become local.
So, Python finds stack
in the scope of isValid
, allows you to access it (just like top
in the first example) and you can access its elements without issue.