Multiple levels of keys and values in Python
The value assigned to a key in a dictionary can itself be another dictionary
creatures = dict()
creatures['birds'] = dict()
creatures['birds']['eagle'] = dict()
creatures['birds']['eagle']['female'] = 0
creatures['birds']['eagle']['female'] += 1
You need to explicitly create each dictionary, though. Unlike Perl, Python does not automatically create a dictionary when you attempt to treat the value of an unassigned key as such.
Unless, of course, you use a defaultdict
:
from collections import defaultdict
creatures = defaultdict( lambda: defaultdict(lambda: defaultdict( int )))
creatures['birds']['eagle']['female'] += 1
For arbitrary levels of nesting, you can use this recursive definition
dd = defaultdict( lambda: dd )
creatures = dd
creatures['birds']['eagle']['female'] = 0
In this case, you do need to explicitly initialize the integer value, since otherwise the value of creatures['birds']['eagle']['female']
will be assumed to be another defaultdict
:
>>> creatures = dd
>>> type(creatures['birds']['eagle']['female'])
<class 'collections.defaultdict'>
If you just have to "count" things -- and assuming the data file contains all the required level of "hashes" -- that will do the trick:
import collections
result = collections.defaultdict(int)
with open("beast","rt") as f:
for line in f:
hashes = line.split()
key = '-'.join(hashes)
result[key] += 1
print result
Producing the result:defaultdict(<type 'int'>, {'Mammals-whales-Male': 1, 'Birds-Eagle-Female': 2})
If you require nested dictionary -- post-processing of that result is still possible...