0

This is my JSON data. JSON data consists of some properties but I only need command and subcommands properties.

{
  command: 'abc',
  depth: 1,
  help: '...',
  subcommands:[
    {
      command: 'abc folder',
      depth: 2,
      help: '...',
      subcommands:[
        {
          command: 'abc folder add',
          depth: 3,
          help: '...',
          subcommands:[
            {
              command: 'abc folder add id',
              depth: 4,
              help: '...',
              subcommands: []
            },
            {
              command: 'abc folder add type',
              depth: 4,
              help: '...',
              subcommands: []
            },
            {
              command: 'abc folder add name',
              depth: 4,
              help: '...',
              subcommands: []
            }]
        }],
        {
          command: 'abc folder list',
          depth: 3,
          help: '...',
          subcommands: []
        },
        {
          command: 'abc folder view',
          depth: 3,
          help: '...',
          subcommands: [
            {
              command: 'abc folder view id',
              depth: 4,
              help: '...',
              subcommands: []
            },
            {
              command: 'abc folder view type',
              depth: 4,
              help: '...',
              subcommands: []
            },
            {
              command: 'abc folder view name',
              depth: 4,
              help: '...',
              subcommands: []
            }
        }]
    }]
}

Nested dictionary I'd like to retrieve from the JSON data is following:

{
  'abc':
    {
      'folder':
        {
          'add':
            {
              'id': {},
              'type': {},
              'name': {}
            },
          'list': {},
          'view':
            {
              'id': {},
              'type': {},
              'name': {}
            }
        }
    }
}

I need to use recursive function so that it will work for deeper properties. It only needs to use command and subcommands. If there's subcommands has empty value then in result, related property's value should also be empty. Please post your suggestion that effectively makes a nested python dictionary.

All your answers will be appreciated. Thanks.

2 Answers 2

1

An elegant mutual recursive form -

def solution(t = {}):

  def one(t, pre):
    if not t:
      return {}
    if isinstance(t, dict):
      return \
        { t['command'][len(pre):]: 
            one
              ( t['subcommands']
              , t['command'] + ' '
              )
        }
    elif isinstance(t, list):
      return many(t, pre)
    else:
      raise TypeError

  def many(ts, pre):
    if not ts:
      return {}
    else:
      return { **one(ts[0], pre), **many(ts[1:], pre) }

  return one(t, "")

As @Ajax1234 points out, you have to fix your input subcommands to use a list -

d = \
  {'command': 'abc', 'depth': 1, 'help': '...', 'subcommands': [{'command': 'abc folder', 'depth': 2, 'help': '...', 'subcommands': [{'command': 'abc folder add', 'depth': 3, 'help': '...', 'subcommands': [{'command': 'abc folder add id', 'depth': 4, 'help': '...', 'subcommands': []}, {'command': 'abc folder add type', 'depth': 4, 'help': '...', 'subcommands': []}, {'command': 'abc folder add name', 'depth': 4, 'help': '...', 'subcommands': []}]}, {'command': 'abc folder list', 'depth': 3, 'help': '...', 'subcommands': []}, {'command': 'abc folder view', 'depth': 3, 'help': '...', 'subcommands': [{'command': 'abc folder view id', 'depth': 4, 'help': '...', 'subcommands': {}}, {'command': 'abc folder view type', 'depth': 4, 'help': '...', 'subcommands': {}}, {'command': 'abc folder view name', 'depth': 4, 'help': '...', 'subcommands': {}}]}]}]}

print(json.dumps(solution(d), indent = 2))

Output -

{
  "abc": {
    "folder": {
      "add": {
        "id": {},
        "type": {},
        "name": {}
      },
      "list": {},
      "view": {
        "id": {},
        "type": {},
        "name": {}
      }
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

my bad.. it's using list for subcommands. I forgot to add square brackets. My question is edited now
0

Your structure cannot be converted to a valid Python dictionary without making your subcommands keys map to a list of the commands they actually represent. Then, you can use str.replace with recursion:

from functools import reduce
data = {'command': 'abc', 'depth': 1, 'help': '...', 'subcommands': [{'command': 'abc folder', 'depth': 2, 'help': '...', 'subcommands': [{'command': 'abc folder add', 'depth': 3, 'help': '...', 'subcommands': [{'command': 'abc folder add id', 'depth': 4, 'help': '...', 'subcommands': []}, {'command': 'abc folder add type', 'depth': 4, 'help': '...', 'subcommands': []}, {'command': 'abc folder add name', 'depth': 4, 'help': '...', 'subcommands': []}]}, {'command': 'abc folder list', 'depth': 3, 'help': '...', 'subcommands': []}, {'command': 'abc folder view', 'depth': 3, 'help': '...', 'subcommands': [{'command': 'abc folder view id', 'depth': 4, 'help': '...', 'subcommands': {}}, {'command': 'abc folder view type', 'depth': 4, 'help': '...', 'subcommands': {}}, {'command': 'abc folder view name', 'depth': 4, 'help': '...', 'subcommands': {}}]}]}]}
def get_d(d, p = None):
  return {d['command'] if p is None else d['command'].replace(p, '')[1:]:\
     reduce(lambda x, y:{**x, **y}, [get_d(i, d['command']) for i in d['subcommands']], {})}

import json
print(json.dumps(get_d(data), indent=4))

Output:

{
  "abc": {
     "folder": {
         "add": {
            "id": {},
            "type": {},
            "name": {}
         },
         "list": {},
         "view": {
             "id": {},
             "type": {},
             "name": {}
          }
       }
   }
}

1 Comment

my bad.. it's using list for subcommands. I forgot to add square brackets. My question is edited now

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.