Home > OS >  Iterate over all values in complex Dictionary
Iterate over all values in complex Dictionary

Time:11-25

Goal: to add a ~tag to the tail end of any value, in a complex dictionary, with a % of occurrence.

Code works for "shallow" dictionaries (with no sub-dicts). I want to work with any complex dictionary.

Note: tag includes ~, if when it occurs.


Code:

import re
import random

RE_TAG = re.compile(r". (~. )")
DLM = '~'
tag_occurance = 25  # as %

thisdict =  {
  "Key1~tag": "foo",
  "Key2": "bar",
  "Key3~tag": {
    "Key3.1": "x",
    "Key3.2~tag": "y"
  }
}

def tag(_str):
    m = RE_TAG.match(_str)
    if m:
        return DLM   m[1][1:]  # '~tag'
    else:
        return ''

# Main Process
thisdict = {key: val   tag(key) if random.randint(0, 100) < tag_occurance else val for key, val in thisdict.items()}  # 25% tag

print(thisdict)  # view difference

Error: val is its own a dictionary, hence error.

Traceback (most recent call last):
  File "./prog.py", line 25, in <module>
  File "./prog.py", line 25, in <dictcomp>
TypeError: unsupported operand type(s) for  : 'dict' and 'str'

Desired Output:

{
  "Key1~tag": "foo~tag",  # tag added as postfix concatenated string
  "Key2": "bar",
  "Key3~tag": {
    "Key3.1": "x",
    "Key3.2~tag": "y~tag"  # tag added as postfix concatenated string
  }
}

Cause of Error

thisdict.values() returns the sub-dicts. I'm only interested in their actual sub-values.

print(thisdict.values())
>>> dict_values(['foo', 'bar', {'Key3.1~tag': 'x', 'Key3.2~tag': 'y'}])

Desired iteration:

['foo', 'bar', 'x', 'y']

Please let me know if there is anything else I can add to post.

CodePudding user response:

One approach, as mentioned in the comments, is to write a recursive function:

def nested_tag(d):
    res = {}
    for key, value in d.items():
        if isinstance(value, dict):
            res[key] = nested_tag(value)
        else:
            res[key] = value   tag(key) if random.randint(0, 100) < tag_occurance else value
    return res



final = nested_tag(this_dict)
print(final)

Output

{'Key1~tag': 'foo', 'Key2': 'bar', 'Key3~tag': {'Key3.1': 'x', 'Key3.2~tag': 'y~tag'}}

The above solution assumes the only complex values are dictionaries.

  • Related