efirvida efirvida - 7 months ago 24
Python Question

Best way to format a nested Python dictionary to be rendered in a jinja2 templates

Hi I have a Python nested dictionaries like this:

fv_solution = {
'relaxationFactors':
{
'fields':
{
'\"(p|pa)\"': 0.3,
'alpha': 0.1,
},
'equations':
{
'\"(U|Ua)\"': 0.7,
'\"(k|epsilon)\"': 0.7,
}
},
'relaxationFactors2':
{
'fields':
{
'\"(p|pa)\"': 0.3,
'alpha': 0.1,
},
'equations':
{
'\"(U|Ua)\"': 0.7,
'\"(k|epsilon)\"': 0.7,
}
}
}


And I want to render to file like this:

relaxationFactors
{
fields
{
"(p|pa)" 0.3;
alpha 0.1;
}
equations
{
"(U|Ua)" 0.7;
"(k|epsilon)" 0.7;
}
}

relaxationFactors2
{
fields
{
"(p|pa)" 0.3;
alpha 0.1;
}
equations
{
"(U|Ua)" 0.7;
"(k|epsilon)" 0.7;
}
}


My best approach was using the replace filter but besides that its not a elegant solution the result is not as desired

my filter

{{ data|replace(':',' ')|replace('{','\n{\n')|replace('}','\n}\n')|replace(',',';\n')|replace('\'','') }}


result

{ # <- not needed
relaxationFactors2
{
fields
{
alpha 0.1;
"(p|pa)" 0.3 # <- missing ;
}
; # <- aditional ;
equations
{
"(U|Ua)" 0.7;
"(k|epsilon)" 0.7 # <- missing ;
}

} # <- not needed
; # <- aditional ;
relaxationFactors
{
fields
{
alpha 0.1;
"(p|pa)" 0.3 # <- missing ;
}
; # <- aditional ;
equations
{
"(U|Ua)" 0.7;
"(k|epsilon)" 0.7 # <- missing ;
}

}

} # <- not needed ;

Answer

You should write a custom filter ...

def format_dict(d, indent=0):
    output = []
    for k, v in d.iteritems():
        if isinstance(v, dict):
            output.append(indent*' ' + str(k))
            output.append(indent*' ' + '{')
            output.append(format_dict(v, indent+4))
            output.append(indent*' ' + '}')
        else:
            output.append(indent*' ' + str(k).ljust(16) + str(v) + ';')
    return '\n'.join(output)

... and set it up as described officially here or, with a full example, here. Then, you can do:

{{ data|format_dict }}
Comments