Better dict of dicts

DillonCo dillonco at comcast.net
Thu Apr 19 20:38:06 EDT 2007


On Thursday 19 April 2007, Bill Jackson wrote:
> Martin v. Löwis wrote the following on 04/19/2007 02:43 PM:
> > Bill Jackson schrieb:
> >> I have a dictionary of dictionaries where the keys are typically very
> >> long tuples and repeated in each inner dictionary.
> >
> > What I don't understand here: you say the keys are tuples, yet later,
> > you show that the keys are strings. Which one is it?
>
> Sorry, I was just lazy.  The keys will always be tuples...tuple of
> strings, tuples of numbers, tuples of objects....simply tuples.

That'll change things a bit because intern only works with strings.

Of course, It's not so big a deal, but you will have to put together a class 
to implement interning.
I wrote one for fun:

class ITuple(tuple):
	_interns={}
	def __new__(cls, tup):
		if tup not in cls._interns:
			itup=tuple.__new__(cls, tup)
			cls._interns[tup]=itup
		return cls._interns[tup]
	def __init__(self, *args):
		#Prevent multiple calls to __init__
		if hasattr(self, "_inited"): return
		tuple.__init__(self, *args)
		self._inited=True
	def __eq__(self, o):
		#If the other is an ITuple, self==o iff self is o
		if isinstance(o, ITuple):
			return self is o
		return tuple.__eq__(self, o)


>>> t1=(1,2,3,4); t2=(1,2,3,4)
>>> ti1=ITuple(t1); ti2=ITuple(t2)
>>> print t1==t2, t1 is t2
True False
>>> print ti1==ti2, ti1 is ti2
True True

That seems to work.  Something to note is that the call overhead of the __eq__ 
function is large enough that unless you have a slow comparing tuple, 
comparisons will be faster without it.  Comparisons are fast if they are done 
internally; so between builtin objects or identical (" is ") objects.

For an example, suppose you have:

class TTT(object):
    def __eq__(self, o): return True
a,b=TTT(),TTT()

Then the follow comparisons are fast:
(1,2,3)==(1,2,3)
(1,2,3,a)==(1,2,3,a)
(0,0,0,a)==(1,2,3,b)

The following are slow:
(1,2,3,a)==(1,2,3,b)

Note that the only slow case is the one where a.__eq__(b) is called.  However, 
a.__eq__(b) is assumed True is "a is b" is True.  So chances are you'll want 
to comment out the __eq__ function.





More information about the Python-list mailing list