idea on how to get/set nested python dictionary values

J

jojoba

hello!

i am trying to come up with a simple way to access my values in my
nested python dictionaries

here is what i have so far, but i wanted to run it by the geniuses out
there who might see any probems with this...
here is an example:

+++++++++++++++++++++++++++++++++++++++
def SetNewDataParam(Data, paramPath, NewData):
ParamList = paramPath.split('/')
numParams = len(ParamList)
for i in range(0, numParams):
if i != (numParams-1):
Data = Data[ParamList]
else:
Data[ParamList] = NewData


Data = {'a':{'b':{'c':1}}}
paramPath = 'a/b/c'
NewData = 666
SetNewDataParam(Data, paramPath, NewData)
+++++++++++++++++++++++++++++++++++++++


so it works!
when i do:
print Data, i get
{'a':{'b':{'c':666}}}


but i am hesistant to be throwing around dictionary references
how is this working????
shouldn't my line above:
Data = Data[ParamList]
screw up my original Data dictionary

Thanks to anyone with comments on this
By the way, i love the idea of using tuples as keys, but my code is so
far along that i dont wanna switch to that elegant way (maybe on a
future project!)
take care,
jojoba
 
W

wittempj

jojoba said:
hello!

i am trying to come up with a simple way to access my values in my
nested python dictionaries

here is what i have so far, but i wanted to run it by the geniuses out
there who might see any probems with this...
here is an example:

+++++++++++++++++++++++++++++++++++++++
def SetNewDataParam(Data, paramPath, NewData):
ParamList = paramPath.split('/')
numParams = len(ParamList)
for i in range(0, numParams):
if i != (numParams-1):
Data = Data[ParamList]
else:
Data[ParamList] = NewData


when I add here
ret Data
Data = {'a':{'b':{'c':1}}}
paramPath = 'a/b/c'
NewData = 666
SetNewDataParam(Data, paramPath, NewData)

and change this to
ret = SetNewDataParam(Data, paramPath, NewData)
print ret
the shell returns me
{'c': 666}
+++++++++++++++++++++++++++++++++++++++


so it works!
when i do:
print Data, i get
{'a':{'b':{'c':666}}}


but i am hesistant to be throwing around dictionary references
how is this working????
shouldn't my line above:
Data = Data[ParamList]
screw up my original Data dictionary

Thanks to anyone with comments on this
By the way, i love the idea of using tuples as keys, but my code is so
far along that i dont wanna switch to that elegant way (maybe on a
future project!)
take care,
jojoba


| would use a recursive approach for this - given that you have a sort
of recursive datastructure:

py> def SetNewDataParam2(Data, NewData):
.... if type(Data[Data.keys()[0]]) == type(dict()):
.... SetNewDataParam2(Data[Data.keys()[0]], NewData)
.... else:
.... Data[Data.keys()[0]] = NewData
....
.... return Data
py> Data = {'a':{'b':{'c':1}}}
py> NewData = 666
py> ret = SetNewDataParam2(Data, NewData)
py> print ret
{'a': {'b': {'c': 666}}}
 
J

jojoba

hey thank you so much!
that should work fantastically
i like your method much better
more elegant
thanks!

jojoba
=)
 
B

bearophileHUGS

py> def SetNewDataParam2(Data, NewData):
... if type(Data[Data.keys()[0]]) == type(dict()):
... SetNewDataParam2(Data[Data.keys()[0]], NewData)
... else:
... Data[Data.keys()[0]] = NewData
...
... return Data
py> Data = {'a':{'b':{'c':1}}}
py> NewData = 666
py> ret = SetNewDataParam2(Data, NewData)
py> print ret
{'a': {'b': {'c': 666}}}

This looks better:

def setNested(nest, val):
el = nest.iterkeys().next()
if isinstance(nest[el], dict):
setNested(nest[el], val)
else:
nest[el] = val
return nest

But maybe something like this is closer to the OP needs:

def setNested(nest, path, val):
nest2 = nest
for key in path[:-1]:
nest2 = nest2[key]
nest2[path[-1]] = val
return nest

ndict = {'a1':{'b1':{'c1':1}, "b2":{"c2":2}}}
print ndict
print setNested(ndict, ("a1", "b1", "c1"), 3)
print setNested(ndict, ("a1", "b2", "c2"), 4)

Output:
{'a1': {'b1': {'c1': 1}, 'b2': {'c2': 2}}}
{'a1': {'b1': {'c1': 3}, 'b2': {'c2': 2}}}
{'a1': {'b1': {'c1': 3}, 'b2': {'c2': 4}}}

(But I don't like too much that kind of in place modify.)

Bye,
bearophile
 
B

bearophileHUGS

Like for the list.sort() method, to remind you that this function
operate by side effect, maybe it's better if it doesn't return the
modified nested dict:

def setNested(nest, path, val):
nest2 = nest
for key in path[:-1]:
nest2 = nest2[key]
nest2[path[-1]] = val

Bye,
bearophile
 
S

Simon Forman

| would use a recursive approach for this - given that you have a sort
of recursive datastructure:

py> def SetNewDataParam2(Data, NewData):
... if type(Data[Data.keys()[0]]) == type(dict()):


Note:

|>> type(dict()) is dict
True

"dict" *is* a type...
 
J

jojoba

Once again,
Thanks to all!!!!
I did not expect to receive such a response.
Very very helpful indeed,

jojoba

o(-_-)o
 
M

metaperl

| would use a recursive approach for this - given that you have a sort
of recursive datastructure:

py> def SetNewDataParam2(Data, NewData):
... if type(Data[Data.keys()[0]]) == type(dict()):
... SetNewDataParam2(Data[Data.keys()[0]], NewData)
... else:
... Data[Data.keys()[0]] = NewData
...

Data[Data.keys()[0]] is used 3 times in the above code. Is there some
way to factor out that usage? I'm just starting python but I'm always
on the lookout for DRY :)
 
W

wittempj

metaperl said:
| would use a recursive approach for this - given that you have a sort
of recursive datastructure:

py> def SetNewDataParam2(Data, NewData):
... if type(Data[Data.keys()[0]]) == type(dict()):
... SetNewDataParam2(Data[Data.keys()[0]], NewData)
... else:
... Data[Data.keys()[0]] = NewData
...

Data[Data.keys()[0]] is used 3 times in the above code. Is there some
way to factor out that usage? I'm just starting python but I'm always
on the lookout for DRY :)

Bearophilehugs gave a much better answer than I did, it also takes away
the need to evaluate the keys() more than one time
 

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

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top