0

I have a number of dot notation strings and their values that I want to use to create a dictionary of dictionaries, but I'm stuck...

For example, I have these strings:

tagPaths = []
tagPaths.append("pump1.runtime")
tagPaths.append("pump1.volume")
tagPaths.append("pump2.runtime")
tagPaths.append("pump2.volume")
tagPaths.append("flowmeter.pv")
tagPaths.append("flowmeter.total")
tagPaths.append("test.testa.testb")

And I have values for each of these strings:

tagValues = []
tagValues.append(10.5)
tagValues.append(256)
tagValues.append(32)
tagValues.append(700)
tagValues.append(5.6)
tagValues.append(900)
tagValues.append("test value")

The resulting dictionary I want to produce is:

{
   "pump1": {
      "runtime": 10.5,
      "volume": 256
      },
   "pump2": {
      "runtime": 32,
      "volume": 700
      },
   "flowmeter": {
      "pv": 5.6,
      "total": 900
      },
   "test": {
      "testa": {
         "testb": "test value"
         }
      }
   }
}

I'm able to create a single string as a nested dictionary with its value assigned, but no idea how to merge them all into a single dictionary of nested dictionaries.

e.g. from this post: How to create a nested dictionary from a list in Python?

tagPaths = []
tagPaths.append("pump1.runtime")
tagPaths.append("pump1.volume")
tagPaths.append("pump2.runtime")
tagPaths.append("pump2.volume")
tagPaths.append("flowmeter.pv")
tagPaths.append("total.volume")
tagPaths.append("test.testa.testb")

tagValues = []
tagValues.append(10.5)
tagValues.append(256)
tagValues.append(32)
tagValues.append(700)
tagValues.append(5.6)
tagValues.append(900)
tagValues.append("test value")

tags = {}
for path, value in zip(tagPaths, tagValues):
   tag = {}
   for i, pathElement in enumerate(reversed(path.split('.'))):
      tag = {pathElement: tag}
      # if we're at the last element in the tag path (i.e. the first reversed), then set the key value to the value of the tag
      if i == 0:
         tag[pathElement] = value
   
   tags.update(tag) # <== This doesn't work as I expected and just replaces all of the nested dictionaries with the `tag` dictionary :/ I need this to additively update, not overwrite update.

Where I'm stuck is the tags.update(tag) part. This produces:

{
    'pump1': {
        'volume': 256 ## 'runtime' key is missing
    },
    'pump2': {
        'volume': 700 ## 'runtime' key is missing
    },
    'flowmeter': {
        'pv': 5.6 ## 'total' key is missing
    },
    'test': {
        'testa': {
            'testb': 'test value'
        }
    }
}

Note: I could have any number of dots in the string, not just 1 or 2 e.g. area.subarea.pump1.status

njminchin
  • 408
  • 3
  • 13
  • 2
    How does https://stackoverflow.com/a/69572347/476 *not* solve your problem? You just call that `set` function described there for each of your path-value pairs. – deceze Mar 29 '22 at 19:51
  • perhaps I was too hasty... perhaps this will work *grimace*. Cheers – njminchin Mar 29 '22 at 20:02

0 Answers0