5

Some friends and I were discussing things related to memory management in Python when we stumbled upon the behaviour below:

In [46]: l = ({} for _ in range(6))

In [47]: [ id(i) for i in l]
Out[47]:
[4371243648, # A
 4371245048, # B
 4371243648, # A
 4371245048, # B
 4371243648, # etc.
 4371245048]

What is surprising here is that we don't seem to have well defined behaviours: the dict is neither a new one each time nor the same reference each time.

On top of that, we got this weird behaviour (not code was run in the interpreter between these two snippets).

In [48]: m = ({} for _ in range(6))

In [49]: [ id(i) for i in m]
Out[49]:
[4371154376, # C
 4371245048, # B (same B as above!)
 4371154376, # C
 4371245048, # B
 4371154376,
 4371245048]

Can anyone explain this behaviour? Using list comprehensions (l = [{} for _ in range(6)]) shows different addresses for each dict.

sitaktif
  • 1,594
  • 13
  • 15
  • [This question](http://stackoverflow.com/q/28963860/2003420) might give you a good idea of what's going on – El Bert Mar 10 '15 at 15:12
  • Did you read the [`id()` function documentation](https://docs.python.org/2/library/functions.html#id)? You missed something crucial there. – Martijn Pieters Mar 10 '15 at 15:13
  • @MartijnPieters I'm not surprised about `id()` reusing the same number. I was surprised about the face that it reused the same number *while I kept a reference to it* (which was my fallacy). – sitaktif Mar 10 '15 at 15:21
  • @sitaktif: right, you are not keeping any references to the `{}` objects you generate; the generator produces them, but doesn't reference them afterward. – Martijn Pieters Mar 10 '15 at 15:31
  • @sitaktif: I think you went wrong here: *the dict is neither a new one each time nor the same reference each time*. It *is* a new dict each time; the left-hand expression in a generator expression is evaluated anew each iteration. – Martijn Pieters Mar 10 '15 at 15:33
  • @MartijnPieters absolutely – sitaktif Mar 11 '15 at 15:15

1 Answers1

4

The dictionaries are being destroyed as soon as they are no longer referenced by the generator. You are comparing the ID's of dead objects, and ID's can be reused.

Kevin
  • 28,963
  • 9
  • 62
  • 81
  • This is exactly what I missed - the fact that with a generator, I lose the reference to the item. Thanks! – sitaktif Mar 10 '15 at 15:20