Fixed keys() mapping

Neil Cerutti horpner at yahoo.com
Thu Jan 11 14:00:15 EST 2007


On 2007-01-11, George Sakkis <george.sakkis at gmail.com> wrote:
> I wrote an 'fkdict' dict-like class for mappings with a fixed
> set of keys but I'm wondering if there's a simpler way to go
> about it.
>
> First off, the main motivation for it is to save memory in case
> of many dicts with the same keys, for example when reading from
> a csv.DictReader or constructing dicts out of rows fetched from
> a database. For example, test_mem(dict) takes up around 246 MB
> according to the Windows task manager while test_mem(fkdict)
> takes around 49 MB:

It occurs to me you could create custom classes using __slots__
to get something similar. It's not terribly convenient.

class XYDict(object):
  __slots__ = ['x', 'y']
  def __getitem__(self, item):
    return self.__getattribute__(item)
  def __setitem__(self, key, item):
    return self.__setattr__(key, item)

This isn't terribly convenient because you have to create a new
class for every new set of keys. It isn't obvious to me how to
program a metaclass to automate the process. A lot more
boilerplate is necessary to act like a dict.

> def test_mem(maptype):
>     d = [(i,str(i)) for i in range(1000)]
>     ds = [maptype(d) for i in xrange(10000)]
>     raw_input('finished')
>
> An additional benefit is predictable ordering (e.g.
> fkdict.fromkeys('abcd').keys() == list('abcd')), like several
> ordered-dict recipes.
>
> The implementation I came up with goes like this: each fkdict
> instance stores only the values as a list in self._values. The
> keys and the mapping of keys to indices are stored in a
> dynamically generated subclass of fkdict, so that self._keys
> and self._key2index are also accessible from the instance. The
> dynamically generated subclasses are cached so that the second
> time an fkdict with the same keys is created, the cached class
> is called.
>
> Since the keys are determined in fkdict.__init__(), this scheme
> requires changing self.__class__ to the dynamically generated
> subclass. As much as I appreciate Python's dynamic nature, I am
> not particularly comfortable with objects that change their
> class and the implications this may have in the future (e.g.
> how well does this play with inheritance). Is this a valid use
> case for type-changing behavior or is there a better, more
> "mainstream" OO design pattern for this ? I can post the
> relevant code if necessary.

Since the type gets changed before __init__ finishes, I don't see
any problem with it. It sounds cool.

-- 
Neil Cerutti
It isn't pollution that is hurting the environment; it's the impurities in our
air and water that are doing it. --Dan Quayle



More information about the Python-list mailing list