In responding to another post on defaultdict, I posted an implementation of a 2-level hashtable, by creating a factory method that returned a defaultdict(dict). The OP of that other thread was trying to build a nested tree from a set of n-tuples, in which the first (n-1) values in each tuple were the keys for navigating down the tree, and the final n'th value was the value for to be assigned to the leaf node. My post worked only if n=2, which fortunately was the test case that the OP gave. But it annoyed me that this required advance knowledge of the number of keys.
I've hacked out this recursivedefaultdict which is a defaultdict(defaultdict(defaultdict(...))), arbitrarily deep depending on the keys provided in the reference.
for kk in sorted(table.keys()): print "-",kk for jj in sorted(table[kk].keys()): print " -",jj for ii in sorted(table[kk][jj].keys()): print " -",ii,table[kk][jj][ii]
prints: - A - B - Z 1 - C - X 3 - Y 2 - B - A - W 4 - B - U 6 - V 5 - D - T 7
On Thu, 2007-08-16 at 20:25 -0700, Paul McGuire wrote: > [...] > I've hacked out this recursivedefaultdict which is a > defaultdict(defaultdict(defaultdict(...))), arbitrarily deep depending > on the keys provided in the reference.
> On Thu, 2007-08-16 at 20:25 -0700, Paul McGuire wrote: > > [...] > > I've hacked out this recursivedefaultdict which is a > > defaultdict(defaultdict(defaultdict(...))), arbitrarily deep depending > > on the keys provided in the reference.
Of course, very short and sweet! Any special reason you wrote: self.default_factory = type(self) instead of: self.default_factory = recursivedefaultdict ?
On Thu, 2007-08-16 at 21:27 -0700, Paul McGuire wrote: > Of course, very short and sweet! Any special reason you wrote: > self.default_factory = type(self) > instead of: > self.default_factory = recursivedefaultdict > ?
Besides a pathological need to be clever? ;) The former keeps the recursive relationship intact if you define a class that inherits from recursivedefaultdict. The latter would create the nested entries of the derived class as "vanilla" recursivedefaultdicts instead of instances of the derived class. Whether this would matter in practice is, of course, a different question.
Paul McGuire wrote: > On Aug 16, 11:19 pm, Carsten Haese <cars...@uniqsys.com> wrote: >> On Thu, 2007-08-16 at 20:25 -0700, Paul McGuire wrote: >>> [...] >>> I've hacked out this recursivedefaultdict which is a >>> defaultdict(defaultdict(defaultdict(...))), arbitrarily deep depending >>> on the keys provided in the reference. >>> Please comment. >>> [...] >>> class recursivedefaultdict(object): >>> def __init__(self): >>> self.__dd = defaultdict(recursivedefaultdict) >>> def __getattr__(self,attr): >>> return self.__dd.__getattribute__(attr) >>> def __getitem__(self,*args): >>> return self.__dd.__getitem__(*args) >>> def __setitem__(self,*args): >>> return self.__dd.__setitem__(*args) >> This is shorter:
>> from collections import defaultdict
>> class recursivedefaultdict(defaultdict): >> def __init__(self): >> self.default_factory = type(self)
> Of course, very short and sweet! Any special reason you wrote: > self.default_factory = type(self) > instead of: > self.default_factory = recursivedefaultdict > ?
It's more robust under subclassing.
regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://del.icio.us/steve.holden --------------- Asciimercial ------------------ Get on the web: Blog, lens and tag the Internet Many services currently offer free registration ----------- Thank You for Reading -------------
> In responding to another post on defaultdict, I posted an > implementation of a 2-level hashtable, by creating a factory method > that returned a defaultdict(dict). The OP of that other thread was > trying to build a nested tree from a set of n-tuples, in which the > first (n-1) values in each tuple were the keys for navigating down the > tree, and the final n'th value was the value for to be assigned to the > leaf node. My post worked only if n=2, which fortunately was the test > case that the OP gave. But it annoyed me that this required advance > knowledge of the number of keys.
> I've hacked out this recursivedefaultdict which is a > defaultdict(defaultdict(defaultdict(...))), arbitrarily deep depending > on the keys provided in the reference.
> for kk in sorted(table.keys()): > print "-",kk > for jj in sorted(table[kk].keys()): > print " -",jj > for ii in sorted(table[kk][jj].keys()): > print " -",ii,table[kk][jj][ii]
> prints: > - A > - B > - Z 1 > - C > - X 3 > - Y 2 > - B > - A > - W 4 > - B > - U 6 > - V 5 > - D > - T 7