Home > database >  Editing dictionary key names based on a specific value
Editing dictionary key names based on a specific value

Time:11-19

After converting to a string represented dictionary in Python I am looking to edit some key names based on a particular value. Here's an example of the dictionary in string format:

s = '{"some.info": "ABC","more.info": "DEF","device.0.Id":"12345678", "device.0.Type":"DEVICE-X", ' \
'"device.0.Status":"ACTIVE", "device.1.Id":"123EFEF8", "device.1.Type":"DEVICE-Y", "device.1.Status":"NOT FOUND", ' \
'"device.2.Id":"ABCD4328", "device.2.Type":"DEVICE-Z", "device.2.Status":"SLEEPING", "other.info":"Hello", ' \
'"additional.info":"Hi Again",}'

I have a working method below, which converts the string into a dictionary, scans for key entries containing '.Type' and drops into a list a tuple of the key section to replace and what to replace it with. However the whole process seems too inefficient, is there a better way to do this?

I have key value pairs of interest in my dictionary like this:

'device.0.Type':'DEVICE-X'
'device.1.Type':'DEVICE-Y'
'device.2.Type':'DEVICE-Z'

What I am looking to do is change all Key name instances of device.X to the value given for key 'device.X.Type'.

For example:

'device.0.Id':'12345678', 'device.0.Type':'DEVICE-X', 'device.0.Status':'ACTIVE',
'device.1.Id':'123EFEF8', 'device.1.Type':'DEVICE-Y', 'device.1.Status':'NOT FOUND', etc

would become:

'DEVICE-X.Id':'12345678', 'DEVICE-X.Type':'DEVICE-X', 'DEVICE-X.Status':'ACTIVE',
'DEVICE-Y.Id':'123EFEF8', 'DEVICE-Y.Type':'DEVICE-Y', 'DEVICE-Y.Status':'NOT FOUND', etc

Basically I am looking to remove the ambiguity of 'device.X' with something that's easier to read based on the device type

Here's my longwinded version:

s = '{"some.info": "ABC","more.info": "DEF","device.0.Id":"12345678", "device.0.Type":"DEVICE-X", ' \
    '"device.0.Status":"ACTIVE", "device.1.Id":"123EFEF8", "device.1.Type":"DEVICE-Y", "device.1.Status":"NOT FOUND", ' \
    '"device.2.Id":"ABCD4328", "device.2.Type":"DEVICE-Z", "device.2.Status":"SLEEPING", "other.info":"Hello", ' \
    '"additional.info":"Hi Again",}'

d = eval(s)

devs = []
for k, v in d.items():
    if '.Type' in k:
        devs.append((k.split('.Type')[0], v))

for item in devs:
    if item[0] in s:
        s = s.replace(item[0], item[1])

s = eval(s)
print(s)

CodePudding user response:

You can solve this by loading the data as a json, then iterating over it:

import json

s = '{"some.info": "ABC","more.info": "DEF","device.0.Id":"12345678", "device.0.Type":"DEVICE-X", "device.0.Status":"ACTIVE", "device.1.Id":"123EFEF8", "device.1.Type":"DEVICE-Y", "device.1.Status":"NOT FOUND", "device.2.Id":"ABCD4328", "device.2.Type":"DEVICE-Z", "device.2.Status":"SLEEPING", "other.info":"Hello", "additional.info":"Hi Again"}'

# load the string to a dictionary
devices_data = json.loads(s)

device_names = {}
for key, value in devices_data.items():
    if key.endswith("Type"):
        # if the key looks like a device type, store the value
        device_names[key.rpartition(".")[0]] = value
        
renamed_device_data = {}
for key, value in devices_data.items():
    x = key.rpartition(".")  # split the key apart
    if x[0] in device_names: # check if the first part matches a device name
        renamed_device_data[f"{device_names[x[0]]}.{x[2]}"] = value  # add the new key to the renamed dictionary with the value
    else:
        renamed_device_data[key] = value  # for non-matches, put them in as is

This could certainly be optimised, but it should work at least!

  • Related