Why I can not change element of list in for cycle?

Why elements of List is not changing? Python.

Yes, I know that I can use
for m in range(0, len(circleList))
and change circleList[m], and it is working fine for numbers.

I am tying to draw 2 moving cirles. If I use list of lists everything works fine:

circleList = [[100], [320]]
def setup():
      size(600,600)
    
def draw():
    background(147)
    global circleList
    for x in circleList:
        circle(x[0], 150, 50)
        x[0] = x[0] + 1
        if x[0] == 600:
            x[0] = -50

But it I use list of numbers, I do not see that element of list is changing:

circleList = [100, 320]
def setup():
    size(600,600)
    
def draw():
    background(147)
    global circleList
    for x in circleList:
        circle(x, 150, 50)
        x = x + 1
        if x == 600:
            x = -50

Why?

In both cases, x is a local variable.

But in the 1st example, each x points to a sublist from circleList; and you use the [] syntax to increment the 1st element of each sublist.

However, in the 2nd example, each x points to an int number; and when you increment x, it creates a new int value which replaces that current int in x.

Given it’s creating a new int value (b/c int is immutable in Python) it’s not the same int that circleList stores anymore.

While in the 1st example, x is mutating each of the same sublists that list circleList points to.

So for each iteration from the 1st example, x temporarily becomes an alias (a different variable that points to the same object of another variable) to 1 of circleList’s sublists; 1st as an alias for circleList[0], and 2nd as an alias for circleList[1].

If you changed x[0] = x[0] + 1 to x = [ x[0] + 1, x[1] ], x would be re-assigned w/ a brand new list, whose changes would not be related to circleList’s own sublists whatsoever!

BtW, you can shorten x[0] = x[0] + 1 to x[0] += 1; and x = x + 1 to just x += 1.

4 Likes

Yes, I can see that a new local variable for x is creating, so when I print, it’s id will be different:

circleList = [100]
def setup():
    size(600,600)
    
def draw():
    noLoop()
    background(147)
    global circleList
    for x in circleList:
        circle(x, 150, 50)
        print(id(x)) #2
        x = x + 1
        print(id(x)) #3
        if x == 600:
            x = -50

Number in python is immutable

1 Like

A bonus experiment:

circleList = [100, 320]

def setup():
    size(600, 600)
    frameRate(.5)
    
def draw():
    background(147)

    for i, x in enumerate(circleList):
        circle(x, 150, 50)

        x += 10

        print i, x, circleList[i] # circleList[] doesn't change!'

        if x == 600: x = -50
2 Likes