dictionary of dictionaries

kettle Josef.Robert.Novak at gmail.com
Sun Dec 9 21:10:04 EST 2007


On Dec 9, 5:49 pm, Marc 'BlackJack' Rintsch <bj_... at gmx.net> wrote:
> On Sun, 09 Dec 2007 00:35:18 -0800, kettle wrote:
> > Hi,
> >  I'm wondering what the best practice is for creating an extensible
> > dictionary-of-dictionaries in python?
>
> >  In perl I would just do something like:
>
> > my %hash_of_hashes;
> > for(my $i=0;$i<10;$i++){
> >     for(my $j=0;$j<10;$j++){
> >    ${$hash_of_hashes{$i}}{$j} = int(rand(10));
> >     }
> > }
>
> > but it seems to be more hassle to replicate this in python.  I've
> > found a couple of references around the web but they seem cumbersome.
> > I'd like something compact.
>
> Use `collections.defaultdict`:
>
> from collections import defaultdict
> from random import randint
>
> data = defaultdict(dict)
> for i in xrange(11):
>     for j in xrange(11):
>         data[i][j] = randint(0, 10)
>
> If the keys `i` and `j` are not "independent" you might use a "flat"
> dictionary with a tuple of both as keys:
>
> data = dict(((i, j), randint(0, 10)) for i in xrange(11) for j in xrange(11))
>
> And just for completeness: The given data in the example can be stored in a
> list of lists of course:
>
> data = [[randint(0, 10) for dummy in xrange(11)] for dummy in xrange(11)]
>
> Ciao,
>         Marc 'BlackJack' Rintsch

Thanks for the heads up.  Indeed it's just as nice as perl.  One more
question though, this defaultdict seems to only work with python2.5+
in the case of python < 2.5 it seems I have to do something like:
#!/usr/bin/python
from random import randint

dict_dict = {}
for x in xrange(10):
    for y in xrange(10):
        r = randint(0,10)
        try:
            dict_dict[x][y] = r
        except:
            if x in dict_dict:
                dict_dict[x][y] = r
            else:
                dict_dict[x] = {}
                dict_dict[x][y] = r

what I really want to / need to be able to do is autoincrement the
values when I hit another word.  Again in perl I'd just do something
like:

my %my_hash;
while(<FILE>){
  chomp;
  @_ = split(/\s+/);
  grep{$my_hash{$_}++} @_;
}

and this generalizes transparently to a hash of hashes or hash of a
hash of hashes etc.  In python < 2.5 this seems to require something
like:

for line in file:
  words = line.split()
  for word in words:
    my_dict[word] = 1 + my_dict.get(word, 0)

which I guess I can generalize to a dict of dicts but it seems it will
require more if/else statements to check whether or not the higher-
level keys exist.  I guess the real answer is that I should just
migrate to python2.5...!

-joe



More information about the Python-list mailing list