The fundamental issue here is that you aren't modifying any objects at all. Consider the following code:
>>> x = 0
>>> y = x
>>> x is y
True
>>> x += 1
>>> x, y
(1, 0)
>>> x is y
False
The operation +=
creates a new int
object and assigns it back to the variable on the left. And because assignment doesn't mutate, no changes have been made to any of the objects in the list or the list itself. Indeed, int
objects and str
objects don't expose any mutator methods, i.e. int
and str
objects are immutable.
There is a subtlety here, though. The +=
operator (which is an augmented assignment operator) will mutate mutable objects (this is a convention, although for built-in types it is guaranteed, but you can implement the augmented assignment operators to do as you please, but you should probably stick to the convention). So for example, another list inside your list would be mutable (since lists are mutable):
>>> x = []
>>> y = x
>>> x is y
True
>>> x += [1]
>>> x, y
([1], [1])
>>> x is y
True
But note, assignment by itself never mutates:
>>> x = []
>>> y = x
>>> x is y
True
>>> x = x + [1]
>>> x, y
([1], [])
>>> x is y
False
So if you had mutated the object:
>>> data = [[1], [2], [3]]
>>> for sub in data:
... sub += [99]
...
>>> data
[[1, 99], [2, 99], [3, 99]]
Or using another mutator method:
>>> data = [[1], [2], [3]]
>>> for sub in data:
... sub.pop()
...
1
2
3
>>> sub
[]
Then the changes would have been reflected in the list.
But simple assignment by itself never mutates:
>>> data = [[1], [2], [3]]
>>> for sub in data:
... sub = sub + [99] # no mutator methods being used
...
>>> data
[[1], [2], [3]]
So, something you must fundamentally understand is when you are working with mutable or immutable objects, and if you are working with mutable object, if you are using mutator methods or not.