简体   繁体   中英

Multilevel dictionary in python

I would like to create a perl style multilevel dict in python however I'm struggling to get this going.

This is what I have tried:

import sys
import csv
import pprint
from collections import defaultdict

hash = defaultdict(dict)
FILE = csv.reader(open('dosageMP.txt', 'rU'), delimiter='\t')
FILE.next()
count = 0
for row in FILE:
    if count < 10:
        print row
        hash[row[0]][row[10]][row[5]] = 1

    count = count+1
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(hash)

This code seems to work well for two level hash[row[0]][row[10]] but won't work for 3 or 4 levels.

Any help would be much appreciated, I'm new to python so I appologies if this is silly question. I can do it in perl but not in python.

The output i would like is :

Center->ROOM1->EXAM1
              ->EXAM2
         ROOM2->EXAM1
              ->EXAM2
              ->EXAM3 
Center2->ROOM3->EXAM1

You're actually looking for a tree structure. There's a simply Python function that provides this structure:

from collections import defaultdict
def tree():
    return defaultdict(tree)

Now you can set it as follows:

hash = tree()
hash['Center']['ROOM1']['EXAM1'] = 1
hash['Center']['ROOM1']['EXAM2'] = 2
hash['Center']['ROOM2']['EXAM1'] = 3
hash['Center']['ROOM2']['EXAM2'] = 4
hash['Center']['ROOM2']['EXAM3'] = 5
hash['Center2']['ROOM3']['EXAM1'] = 6

You can convert these back to dicts using:

def dicts(tree):
    return {key: (dicts(tree[key]) if hasattr(tree[key], 'items') else tree[key]) for key in tree}

For example, here's a prettified output for the hash variable above:

>>> import json
>>> print json.dumps(dicts(hash), indent=4)
{
    "Center2": {
        "ROOM3": {
            "EXAM1": 6
        }
    },
    "Center": {
        "ROOM2": {
            "EXAM2": 4,
            "EXAM3": 5,
            "EXAM1": 3
        },
        "ROOM1": {
            "EXAM2": 2,
            "EXAM1": 1
        }
    }
}

I am not familiar with pearl, but in python you need to initiate a dictionary before calling a specific entry. The way you are using defaultdict, you create a structure that is only two levels deep.

If you don't really need the defaultdict functionality, this is a not so elegant, but fast way to do what you want.

import sys
import csv
import pprint

hash = {}
FILE = csv.reader(open('dosageMP.txt', 'rU'), delimiter='\t')
FILE.next()
count =0
for row in FILE:
    if count <10:
        print row
        hash[row[0]]={}
        hash[row[0]][row[10]]={}
        hash[row[0]][row[10]][row[5]]=1

    count = count+1
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(hash)

I am not familiar with pprint either, but I hope it can handle this structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM