By refering code at
http://initd.org/psycopg/docs/extras.html#dictionary-like-cursor
>>> rec['data']
"abc'def"
>>> rec[2]
"abc'def"
I was wondering how they manage to make a data structure having both tuple and dictionary characteristic?
By refering code at
http://initd.org/psycopg/docs/extras.html#dictionary-like-cursor
>>> rec['data']
"abc'def"
>>> rec[2]
"abc'def"
I was wondering how they manage to make a data structure having both tuple and dictionary characteristic?
Here's a modified version of demas's answer that (I think) will preserve ordering (but will not be efficient):
A dictionary can map any python type against any other python type, so it's simple to retrieve a value where the key is an integer.
Something like that:
In Python the
[]
lookups are handled by the__getitem__
magic method; in other words, when you index a custom class Python will callinstance.__getitem__(...)
and return you the value. This lets you do e.g.There are several natural ways of maintaining the actual data structure; probably the easiest is to maintain both a dict and a list and index into one of them depending on the type of the key.
Notice that this is unnatural; you would expect a dict-like object to treat
0
as a key. it might be worth writing a different method e.g.index
to handle the indexing.You may also wish to implement the
__setitem__
and__contains__
methods.Read the code. Thats my best suggestion.
For example:
And where it is coming from ..
After reading Glenn Maynard's comment on the answer that caused me to delete this one, I've decided to resurrect it. This uses a normal list to store the indices and so will have the same O(1) access.
Here's my take on it. Error handling could probably be improved but I didn't want to clutter up the code too much. I don't know how the original code handled it but why not go ahead and handle slices as well. We can only handle slice assignment for slices that don't create new keys (that is, that don't change the count of items) but we can handle arbitrary slice lookups. Note that it also effectively disallows integer keys. Here's a small demo of it in action.
There's still some stuff to implement.
keys
,items
,iteritems
,update
, etc. but they shouldn't be too hard. Just work withself._keys
and use list comps and generator expressions. for example,iteritems
is just(self._d[key] for key in self._keys)
For update, I would just make sure you're dealing with a dictlike object and then updateself._keys
asself._keys += [key for key in other.keys() if key not in self._keys]
. I might go so far as to define__add__
in essentially the same way.