0

As range objects can be used as dictionary keys, meaning they are immutable, why when doing range(10) is range(10), it doesn't return True?

  • 5
    @Tomerikoo Be careful about testing that way -- doing that actually *does* print the same ID every time. The temporary `range` objects are garbage collected and the IDs get reused. – John Kugelman May 30 '20 at 19:14
  • @bryan60 It seems to be more robust than that. I can define `d = {range(10):5}` and then later on assign `x = range(10)` and have `d[x]` work as expected. Ranges as keys wouldn't be useful without that behavior. – John Coleman May 30 '20 at 19:17
  • 1
    @bryan60 That's also incorrect. `range` overrides equality and hash functions so they're safe to use as keys. – John Kugelman May 30 '20 at 19:18
  • 1
    Why do you think `range(10) is range(10)` **should be true** just because `range` objects are immutable? That doesn't follow at all. – juanpa.arrivillaga May 30 '20 at 19:19
  • 1
    @JohnKugelman you are right! I didn't know the garbage collector is "that fast"... was going to delete my initial comment, but will leave it for constructive discussion – Tomerikoo May 30 '20 at 19:20
  • @Tomerikoo note, CPython uses *reference counting* as its primary automatic memory management system. As an implementation detail, objects are reclaimed *immediately* as soon as their reference count reaches 0. – juanpa.arrivillaga May 30 '20 at 19:55
  • @juanpa.arrivillaga so in that case when using `print(range(10))` in a way the counter goes back to 0 immediately after the line executes? Good to know, thanks! BTW, so save my dignity, I did run said line 2 times in a row **in a console** and got different IDs. But I believe this has something to do with code executed in console having its own memory space per line or something like that – Tomerikoo May 30 '20 at 21:24
  • @Tomerikoo yes, exactly. This is why `print(id(range(10)) == id(range(1)))` might be decieving, because in the expression `id(range(10)) == id(range(10))`, the range objects only exist long enough for the `id` function to be called! But you'll see something different if you do `x, y = range(10), range(10); print(id(x) == id(y))` – juanpa.arrivillaga May 30 '20 at 21:25
  • @juanpa.arrivillaga wow I would guess it works on a line resolution (if that's a thing) but it even gets freed in between evaluations of the same line. interesting, I don't know if it's a typo when you wrote `range(1)` but actually it even works to support your example :D – Tomerikoo May 30 '20 at 21:29
  • @Tomerikoo yes, both illustrate the point :), probably the typo version even better! But yes, things don't work on a line by line basis. You can dissasemble into bytecode to get a better idea of what's going on, `import dis; print(dis.dis('id(range(10)) == id(range(1))'))` – juanpa.arrivillaga May 30 '20 at 21:33
  • 1
    Thanks @juanpa I like the fact that I learn new stuff just from conversation in comments and not even from asking a question. That's why I keep coming :) – Tomerikoo May 30 '20 at 21:35

0 Answers0