When you execute the code, you will get
....
foo += 1
UnboundLocalError: local variable 'foo' referenced before assignment
foo += 1 is actually evaluated like this. foo = foo + 1. So, you are adding 1 to the value of foo and storing it in a variable foo. Since there is an assignment happening, Python assumes that foo is a local variable. But, if it is a local variable, in the expression foo + 1, what would be the value of foo? Python couldn't answer this question. That is why it throws that error.
But, when you do bar[0] += 1, Python evaluates it like this bar[0] = bar[0] + 1. Since, it already knows what bar is, and you are just trying to replace the first element in it, it allows it. In the last case, we were creating a new local variable called foo by doing foo += 1, but here, we are just altering the same object. So Python allows this.
bar[0]is an expression which readsbar, which is allowed in python.