python-3.xvariablesreferencepass-by-referencememory-address

How Python know that it has to give a new address for a variable?


So I found out Python always passed by reference and append always store reference to the appended variables, so I was curious about how append as the following code don't give 10 10s:

ls = []
for i in range(0,10):
    a = 1 + i
    print(id(a))
    ls.append(a)

ls

which gives:

1771416348976
1771416349008
1771416349040
1771416349072
1771416349104
1771416349136
1771416349168
1771416349200
1771416349232
1771416349264
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

So it gives a brand new variable a for every loop. Then I tried the following code:

ls = []
for i in range(0,10):
    a = 1
    print(id(a))
    ls.append(a)

ls

which gives:

1771416348976
1771416348976
1771416348976
1771416348976
1771416348976
1771416348976
1771416348976
1771416348976
1771416348976
1771416348976
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

So it know that doesn't have to give new variables everytime. And finally I tried the following code:

ls = []
for i in range(0,10):
    a = 1
    print(id(a))
    ls.append(a)
    a = 10
    print(id(a))

ls

which gives:

1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
1771416348976
1771416349264
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

apparently python give the same variable 'a' two different address, I thought it will modify the 1 to 10.

So how python allocate address to variable? Seems like it always give a new address for the same variable if it is modified and will reuse the old address if some old value is reassigned to the variable.


Solution

  • You're observing the effect of "interning". Google "python integer interning" and "python string interning". You shouldn't rely on that behavior because it is an implementation detail and not part of the language specification. Also, values like ints are not passed by reference in the sense you seem to mean. You cannot modify the value in the caller's frame. Values like lists and maps are passed by reference in the sense you mean. Changes to a list or map in a called function are visible to the caller. Lastly, the id() function is essentially debugging tool. Any use of it in a program is likely to be wrong.