Le Roy Loïc
Le Roy Loïc

Reputation: 11

Python Concatenate Dictionary keys

I have a dictionary like this:

[
  {
    "context": {
      "id": "aaa",
      "number": "123456",
      "codes": {
        "code": {
          "code": "abc123456",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": null,
      "status": "SUCCESS",
      "description": "abc123456"
    },
    "spec": {
      "code": "abc123456",
      "id": "aaa",
      "url": "https://myexampleabc.mydomain.com",
      "enable": true
    }
  },
  {
    "context": {
      "id": "bbb",
      "number": "789123",
      "codes": {
        "code": {
          "code": "def789123",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": null,
      "status": "SUCCESS",
      "description": "def789123"
    },
    "spec": {
      "code": "def789123",
      "id": "bbb",
      "url": "https://myexampledef.mydomain.com",
      "enable": true
    }
  },
  {
    "context": {
      "id": "ccc",
      "number": "456789",
      "codes": {
        "code": {
          "code": "ghi456789",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": null,
      "status": "SUCCESS",
      "description": "ghi456789"
    },
    "spec": {
      "code": "ghi456789",
      "id": "ccc",
      "url": "https://myexampleghi.mydomain.com",
      "enable": true
    }
  }
]

I want to translate it like this: "key1.key2.key3" : "value"

[
  {
    "context.id": "aaa",
    "context.number": "123456",
    "context.codes.code.code": "abc123456",
    "context.codes.code.codeDesc": "sample",
    "context.codes.code.codeInfo": "example",
    "info.action": "CREATE",
    "info.code": null,
    "info.status": "SUCCESS",
    "info.description": "abc123456",
    "spec.code": "abc123456",
    "spec.id": "aaa",
    "spec.url": "https://myexampleabc.mydomain.com",
    "spec.enable": true
  },
  {
    "context.id": "bbb",
    "context.number": "789123",
    "context.codes.code.code": "def789123",
    "context.codes.code.codeDesc": "sample",
    "context.codes.code.codeInfo": "example",
    "info.action": "CREATE",
    "info.code": null,
    "info.status": "SUCCESS",
    "info.description": "def789123",
    "spec.code": "def789123",
    "spec.id": "bbb",
    "spec.url": "https://myexampledef.mydomain.com",
    "spec.enable": true
  },
  {
    "context.id": "ccc",
    "context.number": "456789",
    "context.codes.code.code": "ghi456789",
    "context.codes.code.codeDesc": "sample",
    "context.codes.code.codeInfo": "example",
    "info.action": "CREATE",
    "info.code": null,
    "info.status": "SUCCESS",
    "info.description": "ghi456789",
    "spec.code": "ghi456789",
    "spec.id": "ccc",
    "spec.url": "https://myexampleghi.mydomain.com",
    "spec.enable": true
  }
]

I try to do it with some loop and isinstance() function, but i can't do what i want. I'm not abble to handle the sublevel for code.

I try something like this

jsondata = json.loads(dataJson)

for level0 in jsondata:
    if isinstance(level0, dict):
      level1Keys = level0.keys()
      level1Values = level0.values()
      print(level1Keys)
      print(level1Values)

I've also tried the .pop() method, but I think I'm not in the right way to do it...

Upvotes: 0

Views: 69

Answers (4)

Epsi95
Epsi95

Reputation: 9047

you can try something like this

l = json.loads("""[
  {
    "context": {
      "id": "aaa",
      "number": "123456",
      "codes": {
        "code": {
          "code": "abc123456",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": null,
      "status": "SUCCESS",
      "description": "abc123456"
    },
    "spec": {
      "code": "abc123456",
      "id": "aaa",
      "url": "https://myexampleabc.mydomain.com",
      "enable": true
    }
  },
  {
    "context": {
      "id": "bbb",
      "number": "789123",
      "codes": {
        "code": {
          "code": "def789123",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": null,
      "status": "SUCCESS",
      "description": "def789123"
    },
    "spec": {
      "code": "def789123",
      "id": "bbb",
      "url": "https://myexampledef.mydomain.com",
      "enable": true
    }
  },
  {
    "context": {
      "id": "ccc",
      "number": "456789",
      "codes": {
        "code": {
          "code": "ghi456789",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": null,
      "status": "SUCCESS",
      "description": "ghi456789"
    },
    "spec": {
      "code": "ghi456789",
      "id": "ccc",
      "url": "https://myexampleghi.mydomain.com",
      "enable": true
    }
  }
]""")

def flatten_dict(d, current_key, final_dict):
    for k,v in d.items():
        if isinstance(v, dict):
            current_key.append(k)
            flatten_dict(v, current_key, final_dict)
            current_key.pop()
        else:
            current_key.append(k)
            final_dict['.'.join(current_key)] = v
            current_key.pop()
    return final_dict

result = [flatten_dict(i, [], {}) for i in l]
[{'context.id': 'aaa',
  'context.number': '123456',
  'context.codes.code.code': 'abc123456',
  'context.codes.code.codeDesc': 'sample',
  'context.codes.code.codeInfo': 'example',
  'info.action': 'CREATE',
  'info.code': None,
  'info.status': 'SUCCESS',
  'info.description': 'abc123456',
  'spec.code': 'abc123456',
  'spec.id': 'aaa',
  'spec.url': 'https://myexampleabc.mydomain.com',
  'spec.enable': True},
 {'context.id': 'bbb',
  'context.number': '789123',
  'context.codes.code.code': 'def789123',
  'context.codes.code.codeDesc': 'sample',
  'context.codes.code.codeInfo': 'example',
  'info.action': 'CREATE',
  'info.code': None,
  'info.status': 'SUCCESS',
  'info.description': 'def789123',
  'spec.code': 'def789123',
  'spec.id': 'bbb',
  'spec.url': 'https://myexampledef.mydomain.com',
  'spec.enable': True},
 {'context.id': 'ccc',
  'context.number': '456789',
  'context.codes.code.code': 'ghi456789',
  'context.codes.code.codeDesc': 'sample',
  'context.codes.code.codeInfo': 'example',
  'info.action': 'CREATE',
  'info.code': None,
  'info.status': 'SUCCESS',
  'info.description': 'ghi456789',
  'spec.code': 'ghi456789',
  'spec.id': 'ccc',
  'spec.url': 'https://myexampleghi.mydomain.com',
  'spec.enable': True}]

Upvotes: 0

John_B
John_B

Reputation: 51

you can try this a snipped way of obtain info, i hope helps your.

level=[]
data={} 
for fields in some_dict :
  data["context.id"] =  fields.get("context").get("id")
  data["context.number"] =  fields.get("context").get("number")
  data["context.codes"] =  fields.get("context").get("codes").get("code")
  data["context.codes.codeDesc"] = fields.get("context").get("codes").get("codeDesc")
  data["context.codes.codeInfo"] =  fields.get("context").get("codes").get("codeInfo")
  data["info.action"] = fields.get("info").get("action")
  level.append(data)
  print(level)

Upvotes: 0

Red
Red

Reputation: 27547

You can try recursion:

lst = [
  {
    "context": {
      "id": "aaa",
      "number": "123456",
      "codes": {
        "code": {
          "code": "abc123456",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": None,
      "status": "SUCCESS",
      "description": "abc123456"
    },
    "spec": {
      "code": "abc123456",
      "id": "aaa",
      "url": "https://myexampleabc.mydomain.com",
      "enable": True
    }
  },
  {
    "context": {
      "id": "bbb",
      "number": "789123",
      "codes": {
        "code": {
          "code": "def789123",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": None,
      "status": "SUCCESS",
      "description": "def789123"
    },
    "spec": {
      "code": "def789123",
      "id": "bbb",
      "url": "https://myexampledef.mydomain.com",
      "enable": True
    }
  },
  {
    "context": {
      "id": "ccc",
      "number": "456789",
      "codes": {
        "code": {
          "code": "ghi456789",
          "codeDesc": "sample",
          "codeInfo": "example"
        }
      }
    },
    "info": {
      "action": "CREATE",
      "code": None,
      "status": "SUCCESS",
      "description": "ghi456789"
    },
    "spec": {
      "code": "ghi456789",
      "id": "ccc",
      "url": "https://myexampleghi.mydomain.com",
      "enable": True
    }
  }
]

def join_keys(d, res={}):
    for k, v in d.items():
        if isinstance(v, dict):
            for key, val in v.copy().items():
                del v[key]
                v[f"{k}.{key}"] = val
                if isinstance(val, str):
                    res[f"{k}.{key}"] = val
            join_keys(v, res)
    return res

for d in lst:
    print(join_keys(d))

Output:

{"context.id": "aaa",
 "context.number": "123456",
 "context.codes.code.code": "abc123456",
 "context.codes.code.codeDesc": "sample",
 "context.codes.code.codeInfo": "example",
 "info.action": "CREATE",
 "info.code": None,
 "info.status": "SUCCESS",
 "info.description": "abc123456",
 "spec.code": "abc123456",
 "spec.id": "aaa",
 "spec.url": "https://myexampleabc.mydomain.com",
 "spec.enable": True}
{"context.id": "bbb",
 "context.number": "789123",
 "context.codes.code.code": "def789123",
 "context.codes.code.codeDesc": "sample",
 "context.codes.code.codeInfo": "example",
 "info.action": "CREATE",
 "info.code": None,
 "info.status": "SUCCESS",
 "info.description": "def789123",
 "spec.code": "def789123",
 "spec.id": "bbb",
 "spec.url": "https://myexampledef.mydomain.com",
 "spec.enable": True}
{"context.id": "ccc",
 "context.number": "456789",
 "context.codes.code.code": "ghi456789",
 "context.codes.code.codeDesc": "sample",
 "context.codes.code.codeInfo": "example",
 "info.action": "CREATE",
 "info.code": None,
 "info.status": "SUCCESS",
 "info.description": "ghi456789",
 "spec.code": "ghi456789",
 "spec.id": "ccc",
 "spec.url": "https://myexampleghi.mydomain.com",
 "spec.enable": True}

Upvotes: 0

user2390182
user2390182

Reputation: 73450

The following recursive function falttens a nested dict to dotted path keys:

def flatten(obj):
    if isinstance(obj, dict):
        res = {}
        for k, v in obj.items():
            f = flatten(v)
            if isinstance(f, dict):
                for k_, v_ in f.items():
                    res[f"{k}.{k_}"] = v_
            else:
                res[k] = f
        return res
    return obj

flattened = list(map(flatten, jsondata))

Upvotes: 1

Related Questions