-1

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

  • 1
    When you don't save the list in a variable, its memory gets garbage collected immediately after the `print()` function returns, and then the same memory is used for the nest list you create. – Barmar Feb 07 '22 at 16:56
  • 2
    *"All the freaking lists value HAVE THE SAME ID???"* - No, All the freaking lists value **HAD** the same ID when they existed. – Kelly Bundy Feb 07 '22 at 16:58
  • 1
    Stack Overflow works better without expletives and all caps. Please avoid both. – jarmod Feb 07 '22 at 16:58
  • @Barmar Actually *before* `print` gets *called*. It's only `id` that has the reference. – Kelly Bundy Feb 07 '22 at 17:00
  • 1
    Sorry, I stuck with these problems for the whole night and can't sleep. So I need the answer urgently. Still when i run print(id(1)) and print(id(2)) (Integer object) it shows different addresses. I wonder why List object is the same? – Quang Hoàng Minh Feb 07 '22 at 17:02
  • I have one simple request. And that is to have lists with different freaking ids attached to their heads. Now my cycloptic colleague informs me that that can't be done. –  Feb 07 '22 at 17:03
  • @KellyBundy I mainly meant that it gets GCed by the time the whole `print(id([1]))` finishes -- the import point is that it's done before you do the next print. Although your point is good, if you do `print(id([1]), id([2]))` you'll get the same ID printed. – Barmar Feb 07 '22 at 17:07
  • @QuangHoàngMinh integers from -5 to 256 are a special case - they are preallocated to specific memory position (thus have individual IDs that do not change for each number) because they are used so often. Check the docs here: https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong – jfaccioni Feb 07 '22 at 17:13

2 Answers2

0

[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
Eli Harold
  • 2,280
  • 1
  • 3
  • 22
  • 2
    OMGGG Thank you so much!!!. I just change the line d=c[:] to a different location and printed id again and now I slowly understand the problem. I think now I get it. Still I think list is stored differently from integer since id(1) id(2) id(n) is always different no matter what order or assignment. – Quang Hoàng Minh Feb 07 '22 at 17:22
  • Yes ints are store before you assign them since python knows how to define them, but a list which is a collection of things has to be assigned as you create it because python doesn't know why items you will put in the list. – Eli Harold Feb 07 '22 at 18:09
  • 1
    @QuangHoàngMinh you may also notice that `id(1)` is equal to `id(c[0])` (for `c = [1]`) since `c[0]` is just referencing the assigned `1`. – Eli Harold Feb 07 '22 at 18:11
0

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!

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252