Arjunsingh
Arjunsingh

Reputation: 763

Python elegant way to order an array of dictionary

I have the data in this format -

[
    {'gstin_code': 'A', 
     'price_effective': 1199.0, 
     'company_id': 489, 
     'month': datetime.datetime(2018, 6, 1, 0, 0), 
     'year': datetime.datetime(2018, 1, 1, 0, 0)
     },
    {'gstin_code': 'B', 
     'price_effective': 1199.0, 
     'company_id': 489, 
     'month': datetime.datetime(2018, 6, 1, 0, 0), 
     'year': datetime.datetime(2018, 1, 1, 0, 0)
     },
    {'gstin_code': 'C', 
     'price_effective': 1199.0, 
     'company_id': 489, 
     'month': datetime.datetime(2018, 6, 1, 0, 0), 
     'year': datetime.datetime(2018, 1, 1, 0, 0)
     }
]

The output expected is this -

{
    "2": {
        "2018": {
            "3": {
                "27AA": 1799
            },
            "4": {
                "03AA": 1299,
                "04AA": 1499,
                "05AA": 699,
                "06AA": 599,
                "07AA": 199,
                "09AA": 499,
                "19AA": 599,
                "23AA": 770,
                "27AA": 420,
                "27AA": 499
            },
            "5": {
                "03AA": 1399,
                "27AA": 399,
                "27AA": 640
            }
         }
     }
  }

i.e {company_id:{year:{month:{gst:price_effective}}}}

Those values also come as None, like company_id, year, month, gst do come as None.

The solution which works is this -

for f_bag in data:
    if f_bag['company_id'] in result and f_bag['company_id'] is not None:
        if f_bag['year'].year in result[f_bag['company_id']] and f_bag['year'].year is not None:
            if f_bag['month'].month in result[f_bag['company_id']][f_bag['year'].year] and f_bag['month'].month is not None:
                if f_bag['gstin_code'] in result[f_bag['company_id']][f_bag['year'].year][f_bag['month'].month] and f_bag['gstin_code'] is not None:
                    pass
                else:
                    result[f_bag['company_id']][f_bag['year'].year][f_bag['month'].month][f_bag['gstin_code']] = f_bag['price_effective']
            else:
                result[f_bag['company_id']][f_bag['year'].year][f_bag['month'].month] = {}
        else:
            result[f_bag['company_id']][f_bag['year'].year] = {}
    else:
        result[f_bag['company_id']] = {}

Any elegant way to avoid these if else statements?

Upvotes: 1

Views: 116

Answers (1)

napuzba
napuzba

Reputation: 6298

with collections.defaultdict you can remove the checks whether the key exist in the dictionary:

from collections import defaultdict
def nested_dict():
    return defaultdict(nested_dict)

def toNested(data):
    nd = nested_dict()
    for aa in data:    
        nd[aa['company_id']][aa['year'].year][aa['month'].month][aa['gstin_code']] = aa['price_effective']
    return nd

import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint( toNested(data) )

Upvotes: 1

Related Questions