[PYTHON] How to make a dictionary with a hierarchical structure.

Can it be implemented in such 5 seconds?

A junior A asked me, "I want to create a dictionary with a hierarchical structure in Python." Of course, "Jean can do that in 5 seconds" I thought. But in the end, it took 30 minutes to answer the question. I spent about 30 minutes explaining it. Also, if you are asked to implement it, you will forget it, so I would like to keep it as a memo.

In the first place, your junior's question is not just that you want to make a double-structured or triple-structured dictionary, but you receive the following input.

example.csv


A1,B1,C1,3
A1,B1,C2,1
A1,B1,C3,5
A1,B2,C1,4
A1,B2,C2,3
A1,B2,C3,1
A1,B3,C1,3
A1,B3,C2,2
A1,B3,C3,5
A2,B1,C1,3
A2,B1,C2,5
A2,B1,C3,3
A2,B2,C1,2
A2,B2,C2,1
A2,B2,C3,3
A2,B3,C1,4
A2,B3,C2,4
A2,B3,C3,5

He wanted to automatically create the following hierarchical dictionary.

{'A1': {'B1': {'C1': 1,
               'C2': 1,
               'C3': 3},
        'B2': {'C1': 3,
               'C2': 3,
               'C3': 4},
        'B3': {'C1': 2,
               'C2': 5,
               'C3': 5}},
 'A2': {'B1': {'C1': 4,
               'C2': 4,
               'C3': 1},
        'B2': {'C1': 1,
               'C2': 3,
               'C3': 3},
        'B3': {'C1': 4,
               'C2': 2,
               'C3': 3}}}

You can't do it in five seconds

So, I had a hard time with this. The first thing I came up with was how to use defaultdict.

import collections
hoge = collections.defaultdict(lambda : collections.defaultdict(lambda : collections.defaultdict(int))

You can create a triple nested dict by using a lambda expression like this. However. This method is subtle. In the first place, it is necessary to know the number of hierarchies in advance, and the number of hierarchies may differ depending on the element, so it is not very general. Furthermore, it is difficult to pickle the defaultdict that defines the default value in the lambda expression. I thought about the following method.

import pprint

def make_tree_dict(inputs):
    tree_dict = {}
    for i, ainput in enumerate(inputs):
        pre_dict = tree_dict
        for j, key in enumerate(ainput):
            if j == len(ainput)-2:
                pre_dict[key] = ainput[-1]
                break
            elif key not in pre_dict:
                pre_dict[key] = {} 
            else:
                pass 
            pre_dict = pre_dict[key] 
    return tree_dict

if __name__ == "__main__":
    pp = pprint.PrettyPrinter(width=10,compact=True)
    inputs = []
    with open("example.csv") as f:
        for line in f:
            line = line.rstrip().split(",")
            inputs.append(line)
    hoge = make_tree_dict(inputs) 
    pp.pprint(hoge) 

By actually running the above program, you can get the output of the hierarchical dict as shown above. It's a strange program that the contents of tree_dict are updated even though it is never directly assigned to tree_dict, but it works. I thought I'd post a commentary, but I don't have time, so this time ...

Incidentally, the above script can be applied to inputs with different numbers of layers for each element as shown below.

example2.csv


A1,B1,C1,1
A1,B1,C2,D1,3
A1,B1,C3,5
A1,B2,C1,D1,5
A1,B2,C2,2
A1,B2,C3,5
A1,B3,C1,2
A1,B3,C2,D1,4
A1,B3,C2,D2,10
A1,B3,C3,2
A2,B1,C1,4
A2,B1,C2,D1,5
A2,B1,C3,5
A2,B2,C1,D1,6
A2,B2,C2,3
A2,B2,C3,D1,8
A2,B3,C1,2
A2,B3,C2,5
A2,B3,C3,4

You can get a dict like this

example2_output


{'A1': {'B1': {'C1': '1',
               'C2': {'D1': '3'},
               'C3': '5'},
        'B2': {'C1': {'D1': '5'},
               'C2': '2',
               'C3': '5'},
        'B3': {'C1': '2',
               'C2': {'D1': '4',
                      'D2': '10'},
               'C3': '2'}},
 'A2': {'B1': {'C1': '4',
               'C2': {'D1': '5'},
               'C3': '5'},
        'B2': {'C1': {'D1': '6'},
               'C2': '3',
               'C3': {'D1': '8'}},
        'B3': {'C1': '2',
               'C2': '5',
               'C3': '4'}}}

Why does it work?

I will add this section if I have time. .. ..

Recommended Posts

How to make a dictionary with a hierarchical structure.
How to convert a class object to a dictionary with SQLAlchemy
How to make a shooting game with toio (Part 1)
How to make a Japanese-English translation
How to make a slack bot
How to make a crawler --Advanced
How to make a recursive function
How to make a deadman's switch
[Blender] How to make a Blender plugin
How to make a crawler --Basic
How to make a Cisco Webex Teams BOT with Flask
How to convert an array to a dictionary with Python [Application]
How to make a simple Flappy Bird game with pygame
How to make a Backtrader custom indicator
How to make a Pelican site map
How to make a command to read the configuration file with pyramid
How to make a surveillance camera (Security Camera) with Opencv and Python
How to read a CSV file with Python 2/3
How to send a message to LINE with curl
How to draw a 2-axis graph with pyplot
How to develop a cart app with Django
I want to make a game with Python
Try to make a "cryptanalysis" cipher with Python
How to make a QGIS plugin (package generation)
I read "How to make a hacking lab"
How to use dictionary {}
Try to make a dihedral group with Python
How to create a multi-platform app with kivy
How to make Linux compatible with Japanese keyboard
A new form of app that works with GitHub: How to make GitHub Apps
How to convert / restore a string with [] in python
[Python] How to draw a line graph with Matplotlib
Try to make a command standby tool with python
Explain in detail how to make sounds with python
How to create a submenu with the [Blender] plugin
How to get a logged-in user with Django's forms.py
How to write a list / dictionary type of Python3
Make a function to describe Japanese fonts with OpenCV
How to make a Python package using VS Code
How to make an HTTPS server with Go / Gin
Basics of PyTorch (2) -How to make a neural network-
[Morphological analysis] How to add a new dictionary to Mecab
[Python] How to create a 2D histogram with Matplotlib
[Python] How to draw a scatter plot with Matplotlib
Add a dictionary to MeCab
How to call a function
Easy to make with syntax
How to update with SQLAlchemy?
How to cast with Theano
How to hack a terminal
Make a fortune with Python
How to Alter with SQLAlchemy?
How to separate strings with','
How to RDP with Fedora31
How to Delete with SQLAlchemy?
Make a fire with kdeplot
How to make a 3D geometric figure with one click [From triangular pyramid to fractal]
How to deploy a web app made with Flask to Heroku
How to put a hyperlink to "file: // hogehoge" with sphinx-> pdf
How to install NPI + send a message to line with python
How to kill a process instantly with Python's Process Pool Executor