Home > Back-end >  Possible to set a Python nested dictionary item using single dot-delimited string path?
Possible to set a Python nested dictionary item using single dot-delimited string path?

Time:10-15

I'd like to be able to set a nested dictionary item using a single dot-delimited string path. For example, given the following dictionary:

data_dictionary = {
  "user_data": {
    "first_name": "Some",
    "last_name": "Guy",
    "phone": "212-111-1234"
  }
}

I'd like to be able to set a specific item using a single string, something like this:

data_dictionary['user_data.phone'] = '818-333-4567'

Anyone know of a library or simple technique for accomplishing something like this?

CodePudding user response:

You could define a little helper function:

def set(obj, path, value):
    *path, last = path.split(".")
    for bit in path:
        obj = obj.setdefault(bit, {})
    obj[last] = value

set(data_dictionary, "user_data.phone", "123")
data_dictionary
# {'user_data': {'first_name': 'Some', 'last_name': 'Guy', 'phone': '123'}}

You can also subclass dict and override __setitem__:

class my_dict(dict):
  def __setitem__(self, item, value):
    if "." in item:
      head, path = item.split(".", 1)
      obj = self.setdefault(head, my_dict())
      obj[path] = value
    else:
      super().__setitem__(item, value)

dd = my_dict({
    "user_data": {
        "first_name": "Some",
        "last_name": "Guy",
        "phone": "212-111-1234"
    }
})

dd["user_data.phone"]  = "123"
dd
# {'user_data': {'first_name': 'Some', 'last_name': 'Guy', 'phone': '123'}}

CodePudding user response:

I suggest something more friendly for nested structures such as Box

Then you can just use dot notation to access as many nests as you want:

from box import Box

data = Box(data_dictionary)
data.user_data.phone = '818-333-4567'
print(data.user_data.phone)

818-333-4567
  • Related