Search code examples
pythonlistmemorydynamic-memory-allocationallocation

How memory address of list in Python work?


Simple code

c=[1]
print (c is [1])
#return false while if c = 1 integer then it would be true

I check the id then turn out

print(id([1]))
print(id([2]))
print(id([1,2,3]))
print(id(c))
#2523446278656 same id but diffrent from id(c)
#2523446278656 same id
#2523446278656 same id
#2523446278848

All the freaking lists values have the same id?? (now I understand that each time I call the print function the id is reset)

And when I just add a simple code

d=c[:]

All the id MAGICALLY CHANGE except id(c), also id(d) is pointed back to the id([1]) above

print(id([1]))
print(id([2]))
print(id([1,2,3]))
print(id(c))
print(id(d))
#2523446278592 diffrent id than aboved
#2523446278592 diffrent id than aboved
#2523446278592 diffrent id than aboved
#2523446278848 the same id as id(c) aboved
#2523446278656 now id(d) is somehow the same with id[1],[1,2],[1,2,3] above

Note that if I just typed 'c[:]' instead of 'd=c[:]' they will still be the same id. Also, my whole code above is on the same script and executed once.

Edit for gaining back asking privileges: Now I understand that there is a Garbage Collector in Python, and every time I assign the value to a variable, the Garbage Collector will come and take the old id, then next time I assign it will use that id again


Solution

  • [1] does not always exist at 2523446278592 (for example) memory is assigned and reassigned all the time. So, for print(id([1])) it assigns [1] to an id so that it can be evaluated, stored, etc. but after it is used in that line it is no longer needed so the space at 2523446278592 is now free again so the next line print(id([2])) can now assign [2] to the id 2523446278592 since it is empty. However, print(id(c)) does not use 2523446278592 (although it is available) because c is already stored at a different location (which is printed instead). Then since d = c[:] creates a new list (not at id(c)) it can then use the open space represented by 2523446278592.

    But also notice the difference here:

    c = [1]
    print(id([1]))
    print(id([2]))
    print(id([1,2,3]))
    print(id(c))
    d = c[:]
    print(id(d))
    

    This prints as you say because d takes the next free id (the on freed up after the prints)

    whereas:

    c = [1]
    d = c[:]
    print(id([1]))
    print(id([2]))
    print(id([1,2,3]))
    print(id(c))
    print(id(d))
    

    this works differently because d is assigned before the prints so the print lines cannot use the id of d for [1] etc. since it is not free so it is different. The output of this case is:

    2346573042880
    2346573042880
    2346573042880
    2346568705216
    2346568705408 #d is different from the print lines