Johnny John Boy
Johnny John Boy

Reputation: 3283

How to create a Python dictionary with sub items from an API?

I've got a response from an API similar to the below which contains a list of products, some of these products are sub products, almost like a bundle. I wanted to produce an output similar to the below:

Main SKU 1
    1 Sub Product(s)
    Sub SKU - Something
    Id

Main SKU 2
    2 Sub Product(s)
    Sub SKU - Something
    Id

With the API data looking like this:

    {
    "DisplayName": "Main SKU 1",
    "Id": "1",
},
    {
    "DisplayName": "Main SKU 2",
    "Id": "2",
},
{
    "DisplayName": "Sub SKU - Something",
    "Id": "3",
    "ParentRef": {
    "value": "1"
    }
},
    {
    "DisplayName": "Sub SKU - Something Else",
    "Id": "4",
    "ParentRef": {
    "value": "2"
    }
},
    {
    "DisplayName": "Sub SKU - Something Else Again", 
    "Id": "5",
    "ParentRef": {
    "value": "2"
    }
}

and I want to create an output to the console like:

Main SKU 1
    1 Sub Product(s)
    Sub SKU - Something
    Id

Main SKU 2
    2 Sub Product(s)
    Sub SKU - Something
    Id

Currently I am iterating through each item to get a list of Main, then again with just the Subs but I'm struggling to put them together. My nested loops are getting out of hand and I'm sure I shouldn't be iterating several times to get the output.

I just want pointing in right direction, I'm not expecting my code to be written for me.

Upvotes: 0

Views: 1192

Answers (2)

Igor Pejic
Igor Pejic

Reputation: 3698

You can do something like this to create a tree structure which will contain a dict in which the key will be the Id of the parent and the value will be the list of its children:

data = {}
for sku in _input
    if 'ParentRef' not in sku:
        data[sku['Id']] = []

for sku in bla:
    if 'ParentRef' in _input:
        data[sku['ParentRef']['value']].append(sku)

Example input:

_input = [
    {
        "DisplayName": "Main SKU 1",
        "Id": "1",
    },
    {
        "DisplayName": "Main SKU 2",
        "Id": "2",
    },
    {
        "DisplayName": "Sub SKU - Something",
        "Id": "3",
        "ParentRef": {
            "value": "1"
        }
    },
    {
        "DisplayName": "Sub SKU - Something Else",
        "Id": "4",
        "ParentRef": {
            "value": "2"
        }
    },
    {
        "DisplayName": "Sub SKU - Something Else Again",
        "Id": "5",
        "ParentRef": {
            "value": "2"
        }
    }
]

Example output:

data = {
    '2': [{
        'DisplayName': 'Sub SKU - Something Else',
        'ParentRef': {
            'value': '2'
        },
        'Id': '4'
    }, {
        'DisplayName': 'Sub SKU - Something Else Again',
        'ParentRef': {
            'value': '2'
        },
        'Id': '5'
    }],
    '1': [{
        'DisplayName': 'Sub SKU - Something',
        'ParentRef': {
            'value': '1'
        },
        'Id': '3'
    }]
}

Note: here I assumed the max depth of the tree is 2. If it can be deeper than that this solution will not work.

Edit: Thanks @alexis; input is built-in; use _input instead.

Upvotes: 1

Amarpreet Singh
Amarpreet Singh

Reputation: 2260

I suppose the response is stored in a list of dict.

This works

res = [
{
    "DisplayName": "Main SKU 1",
    "Id": "1",
},
    {
    "DisplayName": "Main SKU 2",
    "Id": "2",
},
{
    "DisplayName": "Sub SKU - Something",
    "Id": "3",
    "ParentRef": {
    "value": "1"
    }
},
    {
    "DisplayName": "Sub SKU - Something Else",
    "Id": "4",
    "ParentRef": {
    "value": "2"
    }
},
    {
    "DisplayName": "Sub SKU - Something Else Again", 
    "Id": "5",
    "ParentRef": {
    "value": "2"
    }
}
]
count = 0
for item in res:
    parent_id = item.get('ParentRef',{}).get('value')
    if parent_id:
        for parent in res:
            if int(parent['Id']) == int(parent_id):
                count += 1
                parent_Name = parent["DisplayName"]
                print parent_Name
                print count, "Sub Product (s)"
                print item.get("DisplayName")
                print "Id", item.get("Id")

Output is

Main SKU 1
1 Sub Product (s)
Sub SKU - Something
Id 3
Main SKU 2
2 Sub Product (s)
Sub SKU - Something Else
Id 4
Main SKU 2
3 Sub Product (s)
Sub SKU - Something Else Again
Id 5
[Finished in 0.0s]

Upvotes: 0

Related Questions