Home > Back-end >  How memory address of list in Python work?
How memory address of list in Python work?

Time:02-08

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 value 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.

I would really really really appreciate it if someone could draw some pictures with circles (heap, stack, variable, value, etc) to explain my example above. I'm begging you. I stuck with this for whole night and can't sleep until I understand everything

CodePudding user response:

[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

CodePudding user response:

Welcome to the world of temporary objects! When you write c == [1] you create a new list object ([1])and set a reference (c) on it. The lifetime of an object will be the one of its last reference.

But when you write id([1]) you do create a new object (hence a different id), but set no reference to keep it alive so it is immediately destroyed and its address is available for next created object...

BTW, with d = c you create a new reference on the very same object so they will have the same id.

And last but not least, the way the interpretor manages its memory and the object ids only depends on implementation details and you should not even try to guess it... And definitely never rely on any pattern!

  •  Tags:  
  • Related