Q:

Referencing global primitives vs. objects

Could someone please explain the following result in Python?
When running the following snippet of code, Python throws an error, saying that the variable x was referenced before assignment:
x = 1

def increase_x():
    x += 1

increase_x()

The solution, of course, would be to include the line global x after the function declaration for increase_x.
However, when running this next snippet of code, there is no error, and the result is what you expect:
x = [2, -1, 4]

def increase_x_elements():
    for k in range(len(x)):
        x[k] += 1

increase_x_elements()

Is this because integers are primitives in Python (rather than objects) and so x in the first snippet is a primitive stored in memory while x in the second snippet references a pointer to a list object?

A:

As Ffisegydd points out, there is no such thing as a primitive in Python: everything is an object.
You should however note that you are doing two completely different things in those two snippets. In the first, you are rebinding x to the value of x+1. By attempting to assign to x, you've made it locally scoped, so your reference to x+1 fails.
In the second snippet, you are modifying the contents of x, rather than rebinding it. This works because lists are mutable, but the difference is not mutable vs immutable but mutating vs rebinding: rebinding a mutable object would fail just as doing so with an integer does.

