pythondictionarydpath

Substituting sub-dictionaries with specific keys using dpath library


I have a nested input dictionary in this form:

{  "a": {
    "b": {
      "Red": {"min": 0, "max": 1},
      "Green": {"min": 1, "max": 10}
    },
    "c": {
      "Red": {"min": 2, "max": 100}
    }
  }
}

I would like to use the dpath library to search for all the sub-dictionaries in the form {'min': min_value, 'max': max_value} and substitute all such sub-dictionaries with a random number between min_value and max_value.

Expected output

{  "a": {
    "b": {
      "Red": random_number_between_0_and_1,
      "Green": random_number_between_1_and_10
    },
    "c": {
      "Red": random_number_between_2_and_100
    }
  }
}

Note that the code should be as general as possible, as the sub-dict with min/max keys could be at any level in the dictionary. I've been trying to use the regex option of dpath, but I was not able to make good use of it for this application.


Solution

  • I found this solution using filtering with dpath, although I would like a more compact solution using regex, instead of filtering:

    import dpath, random
    
    d = {  "a": {
        "b": {
          "Red": {"min": 0, "max": 1},
          "Green": {"min": 1, "max": 10}
        },
        "c": {
          "Red": {"min": 2, "max": 100}
        }
      }
    }
    
    def find_minmax(x):
        if 'min' in str(x) or 'max' in str(x):
            return True
        return False
    
    for path, value in dpath.search(d, '*/*/*', afilter=find_minmax, yielded=True):
        dpath.set(d, path, random.uniform(value['min'], value['max']))
        
    print(d)
    

    Output:

    {'a': {'b': {'Red': 0.9707850659514508, 'Green': 4.074090994331721}, 'c': {'Red': 55.14734187097105}}}