Python Forum
changing key names in nested dict
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
changing key names in nested dict
#1
hi,

nested dict:

 'identity': {'AIX_REG_CLIENT_VER': '0.1-alpha',
              'HOSTNAME': 'sag01147',
              'SYSTEM_NAME': 'SAG01147_JBOSS4_HA'},
 'nodeinfo': {'CLUSTER_NAME': 'JBOSS4',
              'CLUSTER_NODENAME': 'sag01147',
              'CLUSTER_NODES': 'kug01147,sag01147',
              'CLUSTER_RGS': 'JBOSS33,JBOSS34,JBOSS37,JBOSS38',
              'CL_RGS': 'JBOSS38',
              'CPU_ENTC': '0.60',
              'CPU_VALUE': '4',
              'HAS_COBOL': '0',
              'HAS_JBOSS': '1',
              'HAS_ORACLE': '0',
              'HAS_SAP': '0',
              'HAS_TUXEDO': '0',
              'HAS_UC4': '0',
              'HA_LEVEL': '7.2.4 SP2',
              'IP': {'en0': '172.17.10.147',
                     'en1': '172.16.88.57',
                     'en2': '172.16.12.147'},
              'IP_LONG': {'en0': '172.17.10.147/255.255.248.0/172.17.15.255/',
                          'en1': '172.16.88.57/255.255.192.0/172.16.127.255/sag01147-ipl.some.domain',
                          'en2': '172.16.12.147/255.255.254.0/172.16.13.255/'},
              'IS_CLUSTER': '1',
              'IS_LPM': '0',
              'IS_ZPI': '0',
              'IS_ZPV': '0',
              'Java6': '6.0.0.655',
              'Java6_64': '6.0.0.655',
              'Java7': '7.0.0.665',
              'Java7_64': '7.0.0.665',
              'Java8_64': '8.0.0.610',
              'LOCATION': 'Geiselberg',
              'MACHINE_SERIAL': 'XXXXXX',
              'MAN_SYS_NAME': 'GBG02',
              'MEM_VALUE': '61440',
              'OS_LEVEL': '7200-04-03-2038',
              'STORAGE_VALUE': '258',
              'UPTIME': '54',
              'YUM_REPO': 'IBM'},
 'timestamp': {'DATETIME': '2021-09-09T17:04:32'}}
the usuel flattening code:

for key, value in sample['nodeinfo'].items():
            if isinstance(value, dict):
                for key, value in value.items():
                    entries.append([key, value])
            else:
                entries.append([key, value])
        print(entries)
which produces this

[['HAS_COBOL', '0'], ['HAS_TUXEDO', '0'], ['HAS_SAP', '0'], ['HAS_ORACLE', '0'], ['IS_LPM', '0'], ['HAS_JBOSS', '1'], ['IS_ZPI', '0'], ['IS_ZPV', '0'], ['HAS_UC4', '0'], ['MEM_VALUE', '61440'], ['CPU_VALUE', '4'], ['STORAGE_VALUE', '258'], ['MAN_SYS_NAME', 'GBG02'], ['LOCATION', 'Geiselberg'], ['OS_LEVEL', '7200-04-03-2038'], ['UPTIME', '54'], ['MACHINE_SERIAL', 'XXXXX'], ['CPU_ENTC', '0.60'], ['YUM_REPO', 'IBM'], ['Java6', '6.0.0.655'], ['Java6_64', '6.0.0.655'], ['Java7', '7.0.0.665'], ['Java7_64', '7.0.0.665'], ['Java8_64', '8.0.0.610'], ['IS_CLUSTER', '1'], ['CLUSTER_NAME', 'JBOSS4'], ['CLUSTER_NODES', 'kug01147,sag01147'], ['CLUSTER_NODENAME', 'sag01147'], ['CLUSTER_RGS', 'JBOSS33,JBOSS34,JBOSS37,JBOSS38'], ['HA_LEVEL', '7.2.4 SP2'], ['CL_RGS', 'JBOSS38'], ['en0', '172.17.10.147'], ['en1', '172.16.88.57'], ['en2', '172.16.12.147'], ['en0', '172.17.10.147/255.255.248.0/172.17.15.255/'], ['en1', '172.16.88.57/255.255.192.0/172.16.127.255/sag01147-ipl.some.domain'], ['en2', '172.16.12.147/255.255.254.0/172.16.13.255/']]
as the "en" stuff is only to keep dict keys unique, i need to replace them with the name of the containing dict, "IP" for example.
any clever ideas how to do this in a reuseable way? i tried list str.replace and dict key.pop methods which all failed.
Reply
#2
tried to create a list and then append that to the dict...also no way, whats wrong here? everybody seems to doing like this....

def nested_defaultdict(default_factory, depth=1):
    result = partial(defaultdict, default_factory)
    for _ in repeat(None, depth - 1):
        result = partial(defaultdict, result)
    return result()

 my_dict = nested_defaultdict(list, 5)

ifconfig_output = subprocess.check_output(['/usr/sbin/ifconfig', '-a']).decode('utf-8')
    result = re.findall(r'^(\S+):.*?[\s]+inet ([\d\.]+) netmask ([\w.]+) broadcast ([\d\.]+)', ifconfig_output, re.S | re.M)

    for interface in result:
        if (interface[1] in skip_ip_list):
            continue
        if_name = interface[0]
        ip_addr = interface[1]
        net_mask = dec_netmask(interface[2])
        broad_cast = interface[3]
        r_dns = do_rDNS(interface[1])

        ip_lst = []
        ip_lst.append(("IP", ip_addr))
        print(ip_lst)

    my_dict['nodeinfo']['ip'].append(ip_lst)
[('IP', '172.17.10.147')]
[('IP', '172.16.88.57')]
[('IP', '172.16.12.147')]
Traceback (most recent call last):
  File "/tmp/aix_reg_client_json.py", line 335, in <module>
    reg_client_runner()
  File "/tmp/aix_reg_client_json.py", line 284, in reg_client_runner
    my_dict['nodeinfo']['ip'].append(ip_lst)
AttributeError: 'collections.defaultdict' object has no attribute 'append'
Reply
#3
you mean like this?
entries = []
for key, value in sample['nodeinfo'].items():
    if isinstance(value, dict):
        entries.append([key, list(value.values())])
    else:
        entries.append([key, value])

for i in entries:
    print(*i)
Output:
CLUSTER_NAME JBOSS4 CLUSTER_NODENAME sag01147 CLUSTER_NODES kug01147,sag01147 CLUSTER_RGS JBOSS33,JBOSS34,JBOSS37,JBOSS38 CL_RGS JBOSS38 CPU_ENTC 0.60 CPU_VALUE 4 HAS_COBOL 0 HAS_JBOSS 1 HAS_ORACLE 0 HAS_SAP 0 HAS_TUXEDO 0 HAS_UC4 0 HA_LEVEL 7.2.4 SP2 IP ['172.17.10.147', '172.16.88.57', '172.16.12.147'] IP_LONG ['172.17.10.147/255.255.248.0/172.17.15.255/', '172.16.88.57/255.255.192.0/172.16.127.255/sag01147-ipl.some.domain', '172.16.12.147/255.255.254.0/172.16.13.255/'] IS_CLUSTER 1 IS_LPM 0 IS_ZPI 0 IS_ZPV 0 Java6 6.0.0.655 Java6_64 6.0.0.655 Java7 7.0.0.665 Java7_64 7.0.0.665 Java8_64 8.0.0.610 LOCATION Geiselberg MACHINE_SERIAL XXXXXX MAN_SYS_NAME GBG02 MEM_VALUE 61440 OS_LEVEL 7200-04-03-2038 STORAGE_VALUE 258 UPTIME 54 YUM_REPO IBM
wardancer84 likes this post
Reply
#4
more like this if possible...


[('IP', '172.17.10.147'), ('IP', '172.16.88.57'), ('IP', '172.16.12.147')]
Reply
#5
Why the "5" in the defaultdict factory? That means the 3rd level down is a dict, not a list. So you can't append to it.
wardancer84 likes this post
Reply
#6
good point, maybe i should redo the whole json construction part...

#
(Sep-10-2021, 07:33 AM)bowlofred Wrote: Why the "5" in the defaultdict factory? That means the 3rd level down is a dict, not a list. So you can't append to it.
Reply
#7
Thumbs Up 
ok got it...thank you for pushing me in the right direction Cool i do this for self educational purposes to make me
a little bit mor python fluent, so sorry for some potential stupid questions.

 #
    # IP's ..
    #
    my_dict = nested_defaultdict(list, 2) 
    ifconfig_output = subprocess.check_output(['/usr/sbin/ifconfig', '-a']).decode('utf-8')
    result = re.findall(r'^(\S+):.*?[\s]+inet ([\d\.]+) netmask ([\w.]+) broadcast ([\d\.]+)', ifconfig_output, re.S | re.M)
    ip_lst = []

    for interface in result:
        if (interface[1] in skip_ip_list):
            continue
        if_name = interface[0]
        ip_addr = interface[1]
        net_mask = dec_netmask(interface[2])
        broad_cast = interface[3]
        r_dns = do_rDNS(interface[1])

        ip_lst.append(("IP", ip_addr))


    my_dict['nodeinfo']['ip'].append(ip_lst)
    print(ip_lst)
    print(my_dict['nodeinfo']['ip'])
        #my_dict['nodeinfo']['IP_LONG'].update({if_name : ip_addr + "/" + net_mask + "/" + broad_cast + "/" + r_dns})
'nodeinfo': {'CLUSTER_NAME': 'JBOSS4',
              ...
              'YUM_REPO': 'IBM',
              'ip': [[['IP', '172.17.10.147'],
                      ['IP', '172.16.88.57'],
                      ['IP', '172.16.12.147']]]},
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Updating nested dict list keys tbaror 2 1,276 Feb-09-2022, 09:37 AM
Last Post: tbaror
Star Recursively convert nested dicts to dict subclass Alfalfa 1 2,886 Jan-22-2021, 05:43 AM
Last Post: buran
  Sort a dict in dict cherry_cherry 4 73,301 Apr-08-2020, 12:25 PM
Last Post: perfringo
  convert List of Dicts into a 2 deep Nested Dict rethink 1 3,197 Aug-23-2019, 05:28 PM
Last Post: ichabod801
  Easy way to sort a nested dict Alfalfa 3 5,640 Dec-07-2018, 04:12 PM
Last Post: Alfalfa
  how to create a nested dict.. wardancer84 5 3,647 Nov-23-2018, 04:01 AM
Last Post: Larz60+
  sorting nested dict according to values merlem 6 17,587 Apr-01-2017, 10:01 PM
Last Post: snippsat
  Functions (Arguments Passing,Changing a mutable ,Assignment to Arguments Names) Adelton 2 3,857 Mar-02-2017, 10:23 PM
Last Post: zivoni

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020