-1

I have a big dictionary with smaller dictionaries inside, and i'm trying to get the values inside that aren't dictionaries (but strings, lists or integers), with their "path". I tried to use DFS (Depth First Search) techniques, but without success. Here is a sample of my big dictionary :

{
    'visPlaneSection':
    {
        'ValueMode': 'Single Section',
        'OriginInput': '[0.4, 1.3877787807814457E-17, -8.4350929019372245E-16] m,m,m',
        'OrientationInput': '[1.0, 0.0, -3.3133218391157016E-16] m,m,m',
        'CoordinateSystem': 'Laboratory->Reference',
        'InputPartsInput': '[Region]',
        'ValueIndex': '-1',
        'visSingleValue':
        {
            'ValueQuantityInput': '0.0 m'
        }
    },
    'ChildrenCount': '2'
}

The data i need is : visPlaneSection.ValueMode = 'Single Section'

  • visPlaneSection.ValueMode = 'Single Section'

  • visPlaneSection.OriginInput = [0.4, 1.3877787807814457E-17, -8.4350929019372245E-16] m,m,m

  • ...ect...
  • visPlaneSection.visSingleValue.ValueQuantityInput = '0.0 m'
    How should i do that ? It might be a tree discovery in depth issue, but i don't know how to implement that on my problem.

[EDIT] : To be more specific, here's what I have today :
def test(dictio, path=[]): print(path) if type(dictio) == dict: for k in dictio.keys(): if path == []: path.append(k) else: new_path = path[-1] + "." + k path.append(new_path) test(dictio[k], path) else: path.pop()

So, with the dictionary i showed you, the final element of each lists is the path i want, but it is not working perfectly :
[] ['visPlaneSection'] ['visPlaneSection', 'visPlaneSection.ValueMode'] ['visPlaneSection', 'visPlaneSection.OriginInput'] ['visPlaneSection', 'visPlaneSection.OrientationInput'] ['visPlaneSection', 'visPlaneSection.CoordinateSystem'] ['visPlaneSection', 'visPlaneSection.InputPartsInput'] ['visPlaneSection', 'visPlaneSection.ValueIndex'] ['visPlaneSection', 'visPlaneSection.visSingleValue'] ['visPlaneSection', 'visPlaneSection.visSingleValue', 'visPlaneSection.visSingleValue.ValueQuantityInput'] ['visPlaneSection', 'visPlaneSection.visSingleValue', 'visPlaneSection.visSingleValue.ChildrenCount']
We have here visPlaneSection.visSingleValue.ChildrenCount instead of visPlaneSection.ChildrenCount for the last element, that's where my issue is.
Thanks for your patience and answers

2 Answers2

0

You didn't mention the python version you're using to do this, python 3.4+ would look much better with yield from syntax and whatnot. Here's what a came up with for python 2.7:

def deconstruct(node, path=None):
    if not path:
        path = []

    for key, value in node.items():
        if isinstance(value, dict):
            for sub_value in deconstruct(value, path + [key]):
                yield sub_value
        else:
            yield (value, '.'.join(path + [key]))

if __name__ == '__main__':
    for value, path in deconstruct(input_dict):
        print path, '=', value

If execution speed is your concern - you might want to replace the list with string in path variable.

Rusty
  • 904
  • 4
  • 10
-1

What do you need to do with the data? If you just want to print it, you need something like this:

def _print_dict(s,d):
    for k,v in d.iteritems():
        dot = "." if s else ""
        p="{}{}{}".format(s,dot,k)
        if isinstance(v,dict):            
            _print_dict(p,v)
        else:
            print "{} = {}".format(p,str(v))

and then:

_print_dict('',d)
urim
  • 591
  • 4
  • 13
  • That's pretty close to what i'm searching for, but i need the path (your 's') to fit each data. Here, i have with your program : visPlaneSection.ValueMode.OriginInput.OrientationInput.CoordinateSystem.InputPartsInput.ValueIndex.visSingleValue.ValueQuantityInput. = 0.0 m Or i need visPlaneSection.visSingleValue.ValueQuantityInput = '0.0 m' – M. Charlélie Jul 04 '16 at 13:57
  • @M.Charlélie , you're right, fixed the code now – urim Jul 05 '16 at 10:36