0

My question might seem weird and ambiguous, check the following code:

def foo():
  for _ in range(4):
    x = []
    print(id(x))
    some_handler(x)

On console you would see, for example:

4319661960
4319191112
4319661960
4319191112

As well known, id()gives an opaque value as identifier to object. In the code snippet above, I do expect four different value thus I actually initiate x to be an empty list, so I will do something to it later in some_handler() function. Now I cannot, because x will keep historical value from previous run in the loop.

I many time get tuck into some obvious and silly trap. What I got wrong here?

Murphy Meng
  • 237
  • 3
  • 8
  • Take a look, here has a full explanation: https://stackoverflow.com/questions/40514829/different-class-instances-use-same-memory-location – Kafels Apr 28 '19 at 15:21
  • 1
    Each time through the loop, python is at liberty to dispose of `x` and create a new list for `x`. There is a chance that the new list will occupy the same address on the heap as the old one. If, however, you keep one or more of these lists, any new list cannot occupy the same space as an existing one. – quamrana Apr 28 '19 at 15:22
  • Short answer: The `id` of an object is only guaranteed to be unique for the life of that object. If the object goes away, that `id` can be reused. – ShadowRanger Apr 28 '19 at 15:24
  • Yes. thanks guys. Particularly the link given by @kafels is helpful. Looks like I do not have too much choice but clean the value of x in the end of each run of loop manually to make it work! – Murphy Meng Apr 28 '19 at 15:34
  • @MurphyMeng can I ask what it is you're trying to do here? You pretty much *never* should have to worry about the `id()` of anything in Python... – Jon Clements Apr 28 '19 at 15:36
  • Nothing wrong with `id()`, I attempt to do some data handling within a loop and `x` in the snippet is used to keep some intermediate result. I initiate this `x` in the beginning so it starts as an empty list for each run in the loop. Does that make sense? – Murphy Meng Apr 28 '19 at 15:54
  • @MurphyMeng that's fine... just trying to point out that the `id()` really means nothing here... when you do `x = []` in each loop, you're binding a new name `x` to *an* empty list... whether it's happening to occupy the same space as any previously garbage collected object or a brand new one really doesn't matter and nothing you should really be worrying about at all. Does that make sense? – Jon Clements Apr 28 '19 at 16:14

1 Answers1

1

At the end of your loop, if there are no other references to x, the object could be immediately garbage collected. That means the address is eligible to be reused the next time an object is created.

Save off the value of x (e.g. by putting it into another list) and see that the ids are unique.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328