Grouping based on dictionary keys

I have a dictionary as shown below:

    dict_details = {
        'device.dummy.1.id': '1',
        'device.dummy.2.id': '2',
        'device.dummy.1.length': '202',
        'device.dummy.2.length': '203',
        'device.dummy.2.validity': '10001',
        'device.dummy.1.validity': '10002',
        'device.dummy.1.type': 'first',
        'device.dummy.2.type': 'first'
    }

      

I need to create the following dictionary with the above dictionary. This is a group of dictionary values ​​with some unique id that will be present in my dict.

{
    'device.dummy.1': {
        'id': '1',
        'length': '202',
        'validity': '10001',
        'type': 'first'
    },
    'device.dummy.2': {
        'id': '2',
        'length': '203',
        'validity': '10002',
        'type': 'first'
    }
}

      

I tried the following code:

    dict_details = {
        'device.dummy.1.id': '1',
        'device.dummy.2.id': '2',
        'device.dummy.1.length': '202',
        'device.dummy.2.length': '203',
        'device.dummy.2.validity': '10001',
        'device.dummy.1.validity': '10002',
        'device.dummy.1.type': 'first',
        'device.dummy.2.type': 'first'
    }
    s = {}
    dummy = {}
    for key, value in dict_details.items():

        attrib = key.rsplit(".",1)[1]
        macro = key.rsplit(".",1)[0]
        s[attrib] = value
        dummy[macro] = s
    print(dummy)

      

But it generates output as shown below. This is a key value that is overwritten by existing keys.

Look for a simple workaround for the same.

{
    'device.dummy.1': {
        'length': '202',
        'type': 'first',
        'id': '1',
        'validity': '10001'
    },
    'device.dummy.2': {
        'length': '202',
        'type': 'first',
        'id': '1',
        'validity': '10001'
    }
}

      

+3


source to share


3 answers


FROM defaultdict

You can achieve this with defaultdict

:

from collections import defaultdict
dict_details = {
        'device.dummy.1.id': '1',
        'device.dummy.2.id': '2',
        'device.dummy.1.length': '202',
        'device.dummy.2.length': '203',
        'device.dummy.2.validity': '10001',
        'device.dummy.1.validity': '10002',
        'device.dummy.1.type': 'first',
        'device.dummy.2.type': 'first'
    }

new_dict = defaultdict(dict)

for key in dict_details:
    a, b = key.rsplit(".", 1)
    new_dict[a][b] = dict_details[key]

print(new_dict)
# defaultdict(<type 'dict'>, {'device.dummy.1': {'length': '202', 'type': 'first', 'id': '1', 'validity': '10002'}, 'device.dummy.2': {'length': '203', 'type': 'first', 'id': '2', 'validity': '10001'}})

      



With standard dicts

Without, defaultdict

you just need to check if the sublite is not specified before adding the attributes:

dict_details = {
      'device.dummy.1.id': '1',
      'device.dummy.2.id': '2',
      'device.dummy.1.length': '202',
      'device.dummy.2.length': '203',
      'device.dummy.2.validity': '10001',
      'device.dummy.1.validity': '10002',
      'device.dummy.1.type': 'first',
      'device.dummy.2.type': 'first'
  }

dummy = {}

for key, value in dict_details.items():
    attrib, macro = key.rsplit(".",1)
    if not dummy.get(attrib):
        dummy[attrib] = {}
    dummy[attrib][macro] = value

print(dummy)
# {'device.dummy.1': {'length': '202', 'type': 'first', 'id': '1', 'validity': '10002'}, 'device.dummy.2': {'length': '203', 'type': 'first', 'id': '2', 'validity': '10001'}}

      

+3


source


This is because you are reusing s. You probably want to do something more like

dummy.setdefault(macro, {})[attrib] = value

      



This sets the dummy [macro] to an empty dict if there is no dummy [macro] already.

+1


source


import pprint
dict_details = {
        'device.dummy.1.id': '1',
        'device.dummy.2.id': '2',
        'device.dummy.1.length': '202',
        'device.dummy.2.length': '203',
        'device.dummy.2.validity': '10001',
        'device.dummy.1.validity': '10002',
        'device.dummy.1.type': 'first',
        'device.dummy.2.type': 'first'
    }

dummy = {}
for key, value in dict_details.items():
        attrib = key.rsplit(".",1)[1]
        macro = key.rsplit(".",1)[0]
        if macro not in dummy:
          dummy[macro]={}
          dummy[macro][attrib]=value
        else:
          dummy[macro][attrib]=value
pprint.pprint(dummy)

      

RESULT

{'device.dummy.1': {'id': '1',
                    'length': '202',
                    'type': 'first',
                    'validity': '10002'},
 'device.dummy.2': {'id': '2',
                    'length': '203',
                    'type': 'first',
                    'validity': '10001'}}

      

0


source







All Articles