Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python: Iterate and modify a complex dict including lists

I need to iterate through a complex dictionary and modify it according to several conditions.

This is a very basic example of the dict

a = {
   'x' : ["x1", "x2", 'x3'],
   'y' : [
       {'y1' : 1},
       {'y2' : 2.0},
       {'y3' : True},
       {'y4' : 99},
   ],
   'z' : {
      'x' : ["a1", "a2", 'a3'],
      'y' : [
           {'y1' : 66},
           {'y2' : False},
           {'y3' : 3},
           {'y4' : 4.3},
       ]
   },
   'y3' : "Delete Me"
}

ĂŽterating through it, is also no problem like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 pTypes = [str, bool, int, float]
 def parse(d, c):
     t = type(d)
     if t == dict:
         for k, v in d.items():
             parse(v, c+[k])
     elif t == list:
         for i, p in enumerate(d):
             parse(p,c+[i])
     elif t in pTypes:
         print(c,'=>',d)
     else:
         print('Error: ',c,d,t)


 parse(a,[])

My problem is, that I need to delete all items which have a key == ‘y3’ or a value > 50

Additionally all strings need to be enclosed by ‘-‘ like ‘x1’ => ‘-x1-‘

Just modifing the data does not work (is not persistent)

...
elif t in pTypes:
   if t == str:
       d = '-'+d+'-'
...

And I have no idea how to remove items while iterating the dict itself.

Since the dict can be huge, i would prefer not to make a "reduced" copy of the original.

Can anybody help?

>Solution :

The exact expected output is unclear, but since you are iterating a nested structure, better generate a new object.

Keeping your original recursive logic, you should add a return at each step to propagate your objects:

def parse(d):
    if isinstance(d, dict):
        return {k: parse(v) for k, v in d.items()
                if k != 'y3' and not
                (isinstance(v, (int, float)) and v>50)}
    elif isinstance(d, list):
        return [parse(x) for x in d]
    elif isinstance(d, str):
        return f'-{d}-'
    else:
        return d

out = parse(a)

Output:

{'x': ['-x1-', '-x2-', '-x3-'],
 'y': [{'y1': 1}, {'y2': 2.0}, {}, {}],
 'z': {'x': ['-a1-', '-a2-', '-a3-'],
       'y': [{}, {'y2': False}, {}, {'y4': 4.3}]}}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading