String formatting with nested dictionaries

L

linnorm

I've got a bit of code which has a dictionary nested within another
dictionary. I'm trying to print out specific values from the inner
dict in a formatted string and I'm running into a roadblock. I can't
figure out how to get a value from the inner dict into the string. To
make this even more complicated this is being compiled into a large
string including other parts of the outer dict.

mydict = {'inner_dict':{'Value1':1, 'Value2':2}, 'foo':'bar',
'Hammer':'nails'}

print "foo is set to %(foo)s - Value One is: %(inner_dict['Value1'])s
and Value Two is: %(inner_dict['Value2'])s -- Hammers are used to pound
in %(Hammer)s" % mydict

The above fails looking for a key named 'inner_dict['Value1']' which
doesn't exist.

I've looked through the docs and google and can't find anything
relating to this.
 
D

Diez B. Roggisch

I've got a bit of code which has a dictionary nested within another
dictionary. I'm trying to print out specific values from the inner
dict in a formatted string and I'm running into a roadblock. I can't
figure out how to get a value from the inner dict into the string. To
make this even more complicated this is being compiled into a large
string including other parts of the outer dict.

mydict = {'inner_dict':{'Value1':1, 'Value2':2}, 'foo':'bar',
'Hammer':'nails'}

print "foo is set to %(foo)s - Value One is: %(inner_dict['Value1'])s
and Value Two is: %(inner_dict['Value2'])s -- Hammers are used to pound
in %(Hammer)s" % mydict

The above fails looking for a key named 'inner_dict['Value1']' which
doesn't exist.

I've looked through the docs and google and can't find anything
relating to this.

Because it is not supported. You can only use one level of keys, and it
must be strings. So you have to do it like this:


print "foo is set to %(foo)s - Value One is: %(inner_dict['Value1'])s
and Value Two is: %(inner_dict['Value2'])s -- Hammers are used to
poundin %(Hammer)s" % dict(Hammer=mydict['Hammer'],
Value1=mydict["inner_dict"]["Value1"],
Value2=mydict["inner_dict"]["Value2"])


Diez
 
G

Gabriel Genellina

At said:
I've got a bit of code which has a dictionary nested within another
dictionary. I'm trying to print out specific values from the inner
dict in a formatted string and I'm running into a roadblock. I can't
figure out how to get a value from the inner dict into the string. To
make this even more complicated this is being compiled into a large
string including other parts of the outer dict.

mydict = {'inner_dict':{'Value1':1, 'Value2':2}, 'foo':'bar',
'Hammer':'nails'}

print "foo is set to %(foo)s - Value One is: %(inner_dict['Value1'])s
and Value Two is: %(inner_dict['Value2'])s -- Hammers are used to pound
in %(Hammer)s" % mydict

The above fails looking for a key named 'inner_dict['Value1']' which
doesn't exist.

I can think of two ways:

a) Flatten your dictionary. That is, move the contents of inner_dict
onto the outer dict:
mydict.update(mydict['inner_dict'])
Then use single names for interpolation

b) Do the interpolation in two steps.

template = "foo is set to %(foo)s - Value One is: %(Value1)s
and Value Two is: %(Value2)s -- Hammers are used to pound
in %(Hammer)s"
output = template % mydict['inner_dict']
output = output % mydict

Both methods assume that the inner dict takes precedence in case of
name clashes; reverse the order if you want the opposite.


Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas
 
L

linnorm

Gabriel said:
At said:
I've got a bit of code which has a dictionary nested within another
dictionary. I'm trying to print out specific values from the inner
dict in a formatted string and I'm running into a roadblock. I can't
figure out how to get a value from the inner dict into the string. To
make this even more complicated this is being compiled into a large
string including other parts of the outer dict.

mydict = {'inner_dict':{'Value1':1, 'Value2':2}, 'foo':'bar',
'Hammer':'nails'}

print "foo is set to %(foo)s - Value One is: %(inner_dict['Value1'])s
and Value Two is: %(inner_dict['Value2'])s -- Hammers are used to pound
in %(Hammer)s" % mydict

The above fails looking for a key named 'inner_dict['Value1']' which
doesn't exist.

I can think of two ways:

a) Flatten your dictionary. That is, move the contents of inner_dict
onto the outer dict:
mydict.update(mydict['inner_dict'])
Then use single names for interpolation

b) Do the interpolation in two steps.

template = "foo is set to %(foo)s - Value One is: %(Value1)s
and Value Two is: %(Value2)s -- Hammers are used to pound
in %(Hammer)s"
output = template % mydict['inner_dict']
output = output % mydict

Both methods assume that the inner dict takes precedence in case of
name clashes; reverse the order if you want the opposite.


Gabriel Genellina
Softlab SRL

Thanks, I started going with a) only doing it the long way.
(mydict['Value1'] = mydict['inner_dict']['Value1']) mydict.update() is
*much* simpler and less prone to errors too.
 
F

Fredrik Lundh

I've got a bit of code which has a dictionary nested within another
dictionary. I'm trying to print out specific values from the inner
dict in a formatted string and I'm running into a roadblock. I can't
figure out how to get a value from the inner dict into the string. To
make this even more complicated this is being compiled into a large
string including other parts of the outer dict.

mydict = {'inner_dict':{'Value1':1, 'Value2':2}, 'foo':'bar',
'Hammer':'nails'}

print "foo is set to %(foo)s - Value One is: %(inner_dict['Value1'])s
and Value Two is: %(inner_dict['Value2'])s -- Hammers are used to pound
in %(Hammer)s" % mydict

The above fails looking for a key named 'inner_dict['Value1']' which
doesn't exist.

the % operator treats the keys as plain keys, not expressions. if you
trust the template provider, you can use a custom wrapper to evaluate
the key expressions:

mydict = {'inner_dict':{'Value1':1, 'Value2':2}, 'foo':'bar',
'Hammer':'nails'}

class wrapper:
def __init__(self, dict):
self.dict = dict
def __getitem__(self, key):
try:
return self.dict[key]
except KeyError:
return eval(key, self.dict)

print "foo is set to %(foo)s - Value One is: %(inner_dict['Value1'])s
and Value Two is: %(inner_dict['Value2'])s -- Hammers are used to pound
in %(Hammer)s" % wrapper(mydict)

foo is set to bar - Value One is: 1 and Value Two is: 2 -- Hammers are
used to pound in nails

</F>
 
M

Maric Michaud

Le jeudi 24 août 2006 21:02, Fredrik Lundh a écrit :
class wrapper:
     def __init__(self, dict):
        self.dict = dict
     def __getitem__(self, key):
        try:
            return self.dict[key]
        except KeyError:
       

Quite the same idea, but without eval and the need to know the internal dict
arborescence :

In [242]: class nested_dict_wrapper :
.....: def __init__(self, dic) :
.....: self._all = [dic] + [nested_dict_wrapper(v) for v in
dic.values() if isinstance(v, dict)]
.....: def __getitem__(self, v) :
.....: for i in self._all :
.....: try : return i[v]
.....: except KeyError: pass
.....: raise KeyError(v + ' not found in dict and subdicts')
.....:
.....:

In [248]: complex_dict = { '0': 'zero', '1':'one', 'in1' : {'2':'two'}, 'in2':
{'3': 'three', '4' :'four', 'deeper':{'5':'five', '6':'six'}}, '7':'seven' }

In [250]: "%%(%s)s "*7 % tuple(range(7)) % nested_dict_wrapper(complex_dict)
Out[250]: 'zero one two three four five six '

In [251]: "%%(%s)s "*8 % tuple(range(8)) % nested_dict_wrapper(complex_dict)
Out[251]: 'zero one two three four five six seven '

In [252]: "%%(%s)s "*9 % tuple(range(9)) % nested_dict_wrapper(complex_dict)
---------------------------------------------------------------------------
exceptions.KeyError Traceback (most recent
call last)

/home/maric/<ipython console>

/home/maric/<ipython console> in __getitem__(self, v)

KeyError: '8 not found in dict and subdicts'


--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top