An object id is an implementation-defined "blackbox" value. The only garantees are that a given object will keep the same id for all it's lifetime and that no other object (in the same process...) will share this id during this same time (but the id can be reused for another object in the same process one the first object has been garbage collected).
Note that the implementation is free to cache immutable objects for performance reasons, and CPython has indeed been caching some immutable objects under certain circonstances - notably "small" integers (for a definition of "small" that has changed from version to version) and strings that could be valid variables/functions/classes/modules names, but this is really just an implementation detail. FWIW, it looks like some of this caching is not happening at the REPL's top-level anymore (if it ever happened here) - but it still happens in functions defined in the REPL:
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
pythonrc start
pythonrc done
>>> x = 300
>>> y = 300
>>> id(x)
37126296
>>> id(y)
37126248
>>> def foo():
... x = 300; print "id(x): %s" % id(x)
... y = 300; print "id(y): %s" % id(y)
...
>>> foo()
id(x): 37126200
id(y): 37126200
>>> foo()
id(x): 37126200
id(y): 37126200
>>> foo()
id(x): 37126200
id(y): 37126200
>>> id(x)
37126296
>>> id(y)
37126248
To make a long story short: you shouldn't ever care about this (unless you're writing your own python runtime of course).