Hi, Stream of consciousness answer:
So, you want to set things in a dictionary with a statement like d[a][b][c][d] = x, even though d[a] wasn't used before so it's not initialized yet (let alone d[a][b]). Of course, if d is a dict, the d[a] = x works. That's one level deep, and non existing keys are just created for you. More levels is harder. In the collections module, there is a defaultdict object. You can tell it what to use as a default for some value if it doesn't exist yet. Other than that, it works as a normal dict. Say, if we do: from collections import defaultdict d = defaultdict(dict) Then, if you use d[a] when it doesn't exist yet, it will call dict() to create a new dictionary. So now d[a][b] = x works. But d[a][b][c] = x still doesn't, since the newly created dictionary isn't _itself_ a default dictionary - it's a normal dict. Instead of 'dict', we need to give defaultdict a function that takes no arguments and returns a defaultdictionary object. Like d = defaultdict(lambda: defaultdict(dict)) Now d[a][b][c] = x works. But, again, the last one is a dict, so we still can't go deeper... Now of course d = defaultdict(lambda: defaultdict(lambda: defaultdict(dict))) is there. It solves your problem; you can now set d[a][b][c][d] = x. (importantly, you shouldn't mix depths; don't first set d[a][b][c] = 3 and then try to set d[a][b][c][d]; since d[a][b][c] won't be a dictionary anymore). I can't think of a really good generalization, one that will work for all depths. That's the sort of thing you use Lisp, combinators and lots of coffee for. Perhaps later today. For now though: def deep_default_dict(level): if level < 1: raise ValueError() result = dict while level > 1: result = lambda: defaultdict(result) level -= 1 return result d = deep_default_dict(4)() Should give a dictionary for level=1 and the appropriate defaultdict for the number of levels you need. But I can't test right now... Remco On Jan 24, 2008 8:20 AM, Garry Willgoose <[EMAIL PROTECTED]> wrote: > Is there any easy way to create a nested dictionary. I want to be > able to allocate like > > pdb[dataset][modulename][parametername]['value']=value > > where dataset, modulename, parametername are variables that are > determined within loops nested 3 deep, and value comes from a > database call. Prior to the nested loops I do not know what the > values of dataset, modulename, parametername will range over, but I > do know pdb needs to be nested 3 deep. What I'd like to do is > something like this > > pdb={} > for dataset in dataset_list: > modulename_list=getmodules(dataset) > for modulename in modulename_list: > parametername_list=getparameters(dataset,modulename) > for parametername in parametername_list: > value=getvalue(dataset, modulename, parametername) > > pdb[dataset][modulename][parametername]['value']=value > > What I'm currently doing is > > pdb={} > for dataset in dataset_list: > modulename_list=getmodules(dataset) > moduledict={} > for modulename in modulename_list: > parametername_list=getparameters(dataset,modulename) > valuedict={} > for parametername in parametername_list: > value=getvalue(dataset, modulename, parametername) > valuedict['value']=value > # valuedict needs to be a dictionary because there is other stuff > valuedict['otherstuff]=otherstuff > ... > parameterdict[parametername]=valuedict.copy() > moduledict[modeulename]=copy.deepcopy(parameterdict) > pdb[dataset]=copy.deepcopy(moduledict) > > > Now I know the 2nd is not that much more complex but this is a pretty > common construct in what I'm doing so I'm just wondering if there is > a clear and simple shortcut ;-) > > > ==================================================================== > Prof Garry Willgoose, > Australian Professorial Fellow in Environmental Engineering, > Director, Centre for Climate Impact Management (C2IM), > School of Engineering, The University of Newcastle, > Callaghan, 2308 > Australia. > > Centre webpage: www.c2im.org.au > > Phone: (International) +61 2 4921 6050 (Tues-Fri AM); +61 2 6545 9574 > (Fri PM-Mon) > FAX: (International) +61 2 4921 6991 (Uni); +61 2 6545 9574 (personal > and Telluric) > Env. Engg. Secretary: (International) +61 2 4921 6042 > > email: [EMAIL PROTECTED]; > [EMAIL PROTECTED] > email-for-life: [EMAIL PROTECTED] > personal webpage: www.telluricresearch.com/garry > ==================================================================== > "Do not go where the path may lead, go instead where there is no path > and leave a trail" > Ralph Waldo Emerson > ==================================================================== > > > > > > _______________________________________________ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor >
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor