As I wrote elsewhere:
id is only defined as a number unique to the element among currently existing elements. Some Python implementations (in fact, all main ones but CPython) do not return the memory address.
%~> pypy
Python 2.7.3 (480845e6b1dd219d0944e30f62b01da378437c6c, Aug 08 2013, 17:02:19)
[PyPy 2.1.0 with GCC 4.8.1 20130725 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``arguably, everything is a niche''
>>>> a = 1
>>>> b = 2
>>>> c = 3
>>>> id(a)
9L
>>>> id(b)
17L
>>>> id(c)
25L
So you have to guarantee that it is the memory address. Furthermore, because of this Python provides no id → object mapping, especially as the object that an id maps to can be changed if the original is deleted.
You have to ask why you're holding the id. If it's for space reasons, bear in mind that containers actually hold references to items, so [a, a, a, a, a] actually takes less space than [id(a), id(a), id(a), id(a), id(a)]; a.
You can consider also making a dict of {id: val} for all the relevant items and storing that. This will keep val alive, so you can use weakrefs to allow the vals to be garbage collected. Remember, use weakref if you want a weakref.
So basically it's because there's no reliable solution that's platform-independant.
it bothers me that we have an object and something that would give its address
Then just remember that we do not. CPython only optimises id under the (correct) assumption that the address is unique. You should never treat is as an address because it's not defined to be.
Why was this decision made?
Because if we were to access things from their id we'd be able to do all sorts of stupid stuff like accessing uninitialised stuff. It also prevents interpreters from optimising things by moving addresses around (JIT compilers like PyPy could not exist as easily if items had to have memory addresses). Furthermore, there is no guarantee that the item is either alive or even the same item at any point.
When references take less space than an integer (which is a reference + an numeric object) there is no point just not using a reference(or a weakref if preferred), which will always do the right thing.