Many levels of keys and values ​​in Python

I wanted to know if the function I'm trying to implement in python is possible.

I have a global hash called Creatures. Creatures contain sub-hashes called mammals, amphibians, birds, insects.

Mammals have sub-hashes called whales, elephants. Amphibians have sub-hashes called frogs, larvae. Birds have sub-hashes called Eagles, the parrot. Insects have sub-hashes called dragonflies, mosquitoes.

Again, eagles have sub-hashes called men, women.

I count the frequencies of all these creatures from a text file. For example, if the file is in the format below:

Birds Eagle Female Mammals whales Male Birds Eagle Female I should output Creatures[Birds[Eagle[Female]]] = 2 Creatures[mammals[Whales[Male]]] = 1 

Is this possible in Python? How can I do that? I am very new to Python and please help. I am comfortable with dictionaries only up to level 1, i.e. Key-> value. But there are several keys and several values. I am not sure how to do this. I am using python 2.6. Thanks at advace!

+7
source share
3 answers

If you just need to "count" things - and if the data file contains all the necessary level of "hashes" - this 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 

Result: defaultdict(<type 'int'>, {'Mammals-whales-Male': 1, 'Birds-Eagle-Female': 2})

If you need a nested dictionary - post-processing of this result is still possible ...

+2
source

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 

However, you need to explicitly create each dictionary. Unlike Perl, Python does not automatically create a dictionary when you try to process the value of an unassigned key as such.

Unless, of course, you are using defaultdict :

 from collections import defaultdict creatures = defaultdict( lambda: defaultdict(lambda: defaultdict( int ))) creatures['birds']['eagle']['female'] += 1 

For arbitrary nesting levels, you can use this recursive definition.

 dd = defaultdict( lambda: dd ) creatures = dd creatures['birds']['eagle']['female'] = 0 

In this case, you need to explicitly initialize the integer value, since otherwise the value of creatures['birds']['eagle']['female'] will be considered another defaultdict :

 >>> creatures = dd >>> type(creatures['birds']['eagle']['female']) <class 'collections.defaultdict'> 
+23
source

Not elegant, but working:

 result = {} for line in input_file.split("\n"): curdict = result values = line.split(" ") for item in values[:-1]: if item not in curdict: curdict[item] = {} curdict = curdict[item] last_item = values[-1] if last_item not in curdict: curdict[last_item] = 0 curdict[last_item] += 1 

This can probably be written in a cleaner way, but at least it works and allows an arbitrary level of nesting if you do not have another level of nesting for the same β€œentity” (for example, Birds Eagle Female and Birds Eagle do not will work )

+1
source

Source: https://habr.com/ru/post/947495/


All Articles