Building and Transvering multi-level dictionaries

sblakey at freei.net sblakey at freei.net
Tue Mar 21 03:22:44 CET 2000


On 21 Mar, Eric Hagemann wrote:
> Lee,
>     I have been doing somewhat of the same recently. Yours is the first note
> I have seen that talks about pushing the dictionary into multi-dimensions.
> 
> I was actualy out to replicate the ability of multi-dimensional hashs found
> in Perl.
> There are a few references to being able to do this but they were static
> examples.  I needed the capability to generate multidimensional dictionaries
> on the fly.
> 
> Here is what I have come up with.
> 
> #create empty dictionary
> D={}
> 
> #add a key and setup for a sub-dictionary
> if(D.has_key('a') == 0)
>     D['a'] = {}
> 
> #add a sub-level to the dictionary
> if((D['a']).has_key('b') == 0)
>     D['a']['b'] = {}
> 
> When you get to the lowest level stop adding dictionaries and store your
> value.
> To get keys at the different levels use parens
> 
> RootKeys = D.keys()
> firstlevelKeys = (D['a']).keys()
> ........
> 
> Let me know if you have abetter way of doing this.  I would like to
> eliminate the 'if' statement (its not needed in Perl!)
> when adding a new sub-dictionary
> Cheers
> eric
> 
> 
> "Lee Joramo" <ljoramo at nickads.com> wrote in message
> news:200320001753125356%ljoramo at nickads.com...
>> I am trying to build a multi-level dictionary from an text file, and
>> then transverse the dictionary, create formated output. I have been
>> able to do this for a special case where ever piece of data has a fixed
>> number of levels (sub-catagories). However, I am looking for an method
>> that can elegantly handel a dictionary with variable depth.
>>
>> For example, say that I have a file sample.dat with the line format:
>>
>> catagory:sub:sub TAB description
>>
>> ---start sample.dat----
>> animal:mammal:dog             A very lazy dog
>> animal:mammal:dog             Super hunting dog
>> animal:mammal:dog             Not your average hound
>> animal:mammal:cat             Enjoys sleeping in the sun
>> animal:snake                  Beware of the python in the forest
>> animal:fish                   There are many fish in the deep blue sea
>> animal:fish                   Tuna terrorize the oceans
>> plant:tree:evergreen:redwood  Very Very Very Tall
>> ---end sample.dat---
>>
>> The first part of each line is the items classification. The number of
>> sub-catagories is variable.
>>
>> From this file I want to generate a python dictionary:
>>
>> {'animal' : {'mammal' : {'dog' : ('A very lazy dog', 'Super hunting
>> dog', 'Not your average hound'), 'cat' : 'Enjoys sleeping in the sun'},
>> 'snake' : 'Beware of the python in the forest', 'fish' : ('There are
>> many fish in the deep blue sea', 'Tuna terrorize the oceans')},'tree' :
>> {'evergreen' : {'redwood' : 'Very Very Very Tall'}}}
>>
>>
>> Then I want to be able to transvers the dictionary and print an outline:
>>
>> animal
>>    mammal
>>      dog
>>        * A very lazy dog
>>        * Super hunting dog
>>        * Not your average hound
>>      cat
>>        * Enjoys sleeping in the sun
>>      snake
>>        * Beware of the python in the forest
>>      fish
>>        * There are many fish in the deep blue sea
>>        * Tuna terrorize the oceans
>> tree
>>    evergreen
>>      redwood
>>        * Very Very Very Tall
>>
>> Another point that I am interested in is how get a the value of a
>> specific key in an easy way. For example, I know that I can get the
>> value of 'cat':
>>
>> description = mydict['animal']['mammal']['cat']
>>
>> which in my example returns: 'Enjoys sleeping in the sun'
>>
>> However I am looking for a way of doing something like list:
>>
>> compoundkey = 'animal.mammal.cat'
>> description = mydict[compoundkey]
>>
>> Thanks for any suggestions.
>>
>> --
>> --
>> Lee A. Joramo                      ljoramo at nickads.com
>> The Nickel Want Ads                www.nickads.com
>> Internet Manager                   970-242-5555
> 
> 
You can simulate multi-level dictionaries with tuples:
mydict = {}
mydict['animal', 'mammal', 'cat'] = 'Enjoys sleeping in the sun'
This makes the second part of your problem extremely simple:
compundkey= ('animal', 'mammal', 'cat')
description = mydict[compoundkey]

However, this does make the first part (pretty-printing the dictionary
in an outline-like form) more difficult.  Here's my untested stab at it:

keys = mydict.keys()
keys.sort()
for i in range(len(keys)):
    for j in range(len(keys[i])):
	try:
	    if keys[i][j] != keys[i-1][j]:
	    	print keys[i][j]
	    	print '\t'*(j + 1)	# Indent the next line properly
	    	if len(keys[i]) == j:	# No more subkeys
	    	    print '*', mydict[keys[i]]
	    else:
	        print '\t',	# Indent another step
	except IndexError:	# Will happen with line zero
	    print keys[i][j]
	    print '\t'*(j+1)
	    if len(keys[i]) == j:
	        print '*', mydict[keys[i]]

I think this will print out pretty much the outline you want.
	    
			





More information about the Python-list mailing list