[Tutor] Dictionary from a text file

Peter Otten __peter__ at web.de
Thu Oct 31 11:30:26 CET 2013


Nitish Kunder wrote:

> I have a dictionary which is in this format
> for ex:
> 
> {
> '5x' : {
> '50' : {
> 'update' : {
> 'update-from-esxi5.0-5.0_update01' : {
> 'call' : Update,
> 'name' : 'Update50u1',
> 'release' : '15/03/12'
> },
> 'update-from-esxi5.0-5.0_update02' : {
> 'call' : Update,
> 'name' : 'Update50u2',
> 'release' : '21/12/12'
> },
> },
>  'patch' : {
> 'ESXi500-201109001' : {
> 'call' : Patch,
> 'name' :'Patch_501',
> 'release' : '13/09/11'
> },
> 'ESXi500-201111001' : {
> 'call' : Patch,
> 'name' :'ExpressPatch501',
> 'release' : '13/09/11'
> },
>  },
> },
>  '51' : {
> 'update' : {
> 'update-from-esxi5.1-5.1_update01' : {
> 'call' : Update,
> 'name' : 'Update51u1',
> 'release' : '25/04/13'
> },
> },
> 'patch' : {
> 'ESXi510-201210001' : {
> 'call' : Patch,
> 'name' :'ExpressPatch511',
> 'release' : '29/08/13'
> },
> 'ESXi510-201212001' : {
> 'call' : Patch,
> 'name' :'Patch_511',
> 'release' : '20/12/12'
> },
>  },
> },
> },
>  }
> 
> Note: in* 'call' : Update* ,Update it is a function defined in my python
> script. My dictionary is too large so i taught rather than using directly
> in python program I save it in a text file and when needed i assign it to
> dictionary object . How can i assign this text file to dictionary object
> and call it?

You could modify the dict a bit to comply with the json format and then load 
and post-process it to replace names with functions:

import json

def Update(): pass
def Patch(): pass

def post_process(x, names):
    for k, v in x.items():
        if k == u"call":
            x[k] = names[v]
        elif isinstance(v, dict):
            post_process(v, names)

with open("tmp.json") as instream:
    d = json.load(instream)
post_process(d, names={u"Patch": Patch, u"Update": Update})

Another option is to use a function similar to ast.literal_eval() that can 
do name lookups. Here's my adaptation of literal_eval():

import ast

def Update(): pass
def Patch(): pass

def safe_eval(s, names={}):
    node = ast.parse(s, mode="eval")
    if isinstance(node, ast.Expression):
        node = node.body
    def convert(node):
        if isinstance(node, ast.Str):
            return node.s
        elif isinstance(node, ast.Dict):
            return {convert(k): convert(v) for k, v in zip(node.keys, 
node.values)}
        elif isinstance(node, ast.Name):
            try:
                return names[node.id]
            except KeyError:
                raise ValueError("Unresolved name {!r}".format(node.id))

        raise ValueError("Malformed node or string {!r}".format(node))
    return convert(node)

with open("tmp.txt") as instream:
    data = instream.read()

d = safe_eval(data, dict(Update=Update, Patch=Patch))




More information about the Tutor mailing list