1

im having trouble with a recursive function that i'm trying to make so i can transform a json file with several nested dicts and lists (and sometimes nested dicts and lists inside other nested dicts and lists).

basically i'm trying to organize a JSON file in a simple OrderedDict so i can pass it to the MongoDB database

here is the recursive function:

def JSON_Treating(self,json_data):

    headers = []
    data = []
    for key, value in json_data.iteritems():
        headers.append(key)
        try:
            if isinstance(value, (dict,list)):
                if isinstance(value, list) and isinstance(value[0], dict):

                    value = value[0]

                self.JSON_treating(value)

            data.append(value)
        except:
            data.append(value)
            Dict = OrderedDict(zip(headers,dados))

            self.JSON_treating(Dict)


    return Dict

the objective here is, each time the code finds a nested table it gets its headers and values and append the headers to the headers and values to the data, then, when its finished the code will join the headers and the values in order.

My problem is, i cannot get it right, see... Either the code doesn't get all the nested ones or the code simply don't work. Please help Thanks!

EDIT: here is a example of the input JSON

[
{
    "status": 0, 
    "payment_value": 0, 
    "date": "2018-07-28 12:18:00", 
    "Payment": [
        {
            "payment_general": 0, 
            "code": 1, 
            "total_value": 0, 
            "payment_form": "card"
        }
    ], 
    "id__": "", 
    "Product": [
        {
            "sku": "00000", 
            "ID_delivery": null, 
            "ammount": 1, 
            "unitary_value": 55.34, 
            "discount_name": null, 
            "delivery_form": null, 
            "discount_ammount": 0, 
            "delivery_charge": 20.34, 
            "taxes": 0, 
            "comission": null, 
            "id__discount": null
        }
    ], 
    "client": {
        "delivery": {
            "phone": [
                "1", 
                "2"
            ], 
            "fax": null, 
            "name": "A name here", 
            "state_tax": "free", 
            "address": {
                "reference": "a reference here", 
                "complement": "a complement here", 
                "block": "N123", 
                "city": "New York", 
                "road_name": "a road name", 
                "number": "413", 
                "postal_code": "123234", 
                "country": "US", 
                "State": "NY"
            }, 
            "email": "", 
            "document": ""
        }, 
        "taxation": {
            "phones": [
                "1", 
                "2"
            ], 
            "fax": null, 
            "type": "AN", 
            "nome": "a name here", 
            "state_demand": "A-B", 
            "birth_date": "1996-04-01", 
            "sex": "F-M", 
            "address": {
                "reference": "a reference here", 
                "complement": "a complement here", 
                "block": "N123", 
                "city": "New York", 
                "road_name": "a road name", 
                "number": "413", 
                "postal_code": "123234", 
                "country": "US", 
                "State": "NY"
            }, 
            "email": "a e mail ", 
            "document": "a document"
        }
    }, 
    "delivery_prevision": 10
}]

And here is how i need it to be:

{
"status": 0, 
"payment_value": 0, 
"date": "2018-07-28 12:18:00", 
"Payment": ,

"payment_general": 0, 
"code": 1, 
"total_value": 0, 
"payment_form": "card", 
"id__": "", 
"Product":, 
"NDE": "00000", 
"ID_delivery": null, 
"ammount": 1, 
"unitary_value": 55.34, 
"discount_name": null, 
"delivery_form": null, 
"discount_ammount": 0, 
"delivery_charge": 20.34, 
"taxes": 0, 
"comission": null, 
"id__discount": null,
"client": ,
"delivery": ,
"phone": "1" "2",
"fax": null, 
"name": "A name here", 
"state_tax": "free", 
"address": ,
"reference": "a reference here", 
"complement": "a complement here", 
"block": "N123", 
"city": "New York", 
"road_name": "a road name", 
"number": "413", 
"postal_code": "123234", 
"country": "US", 
"State": "NY",

"taxation": ,
"phones": "1",  "2"

"fax": null, 
"type": "AN", 
"nome": "a name here", 
"state_demand": "A-B", 
"birth_date": "1996-04-01", 
"sex": "F-M", 
"address": ,
"reference": 
"a reference here", 
"complement": "a complement here", 
"block": "N123", 
"city": "New York", 
"road_name": "a road name", 
"number": "413", 
"postal_code": "123234", 
"country": "US", 
"State": "NY",
"email": "a e mail ", 
"document": "a document",
"delivery_prevision": 10
}
Vitor Araújo
  • 292
  • 4
  • 19

1 Answers1

1

Does this for you?

class UnknownClassYouNeverShowed(object):
    def JSON_Treating(self, json_data):
        flat_dict = {}
        if isinstance(json_data, list):
            for item in json_data:
                if isinstance(item, (list, dict)):
                    flat_dict.update(self.JSON_Treating(item))
            return flat_dict

        for key, value in json_data.iteritems():
            if isinstance(value, (list, dict)):
                flat_dict.update(self.JSON_Treating(value))
            else:
                flat_dict[key] = value
        return flat_dict

If you really just have the json string, load it and feed it to the function using: import json; data = json.loads(some_json_string) .. you get the idea.


Testing i get this:

import pprint
unknown = UnknownClassYouNeverShowed()
pprint.pprint(unknown.JSON_Treating(data))

Output:

{'ID_delivery': None,
 'State': 'NY',
 'ammount': 1,
 'birth_date': '1996-04-01',
 'block': 'N123',
 'city': 'New York',
 'code': 1,
 'comission': None,
 'complement': 'a complement here',
 'country': 'US',
 'date': '2018-07-28 12:18:00',
 'delivery_charge': 20.34,
 'delivery_form': None,
 'delivery_prevision': 10,
 'discount_ammount': 0,
 'discount_name': None,
 'document': 'a document',
 'email': 'a e mail ',
 'fax': None,
 'id__': '',
 'id__discount': None,
 'name': 'A name here',
 'nome': 'a name here',
 'number': '413',
 'payment_form': 'card',
 'payment_general': 0,
 'payment_value': 0,
 'postal_code': '123234',
 'reference': 'a reference here',
 'road_name': 'a road name',
 'sex': 'F-M',
 'sku': '00000',
 'state_demand': 'A-B',
 'state_tax': 'free',
 'status': 0,
 'taxes': 0,
 'total_value': 0,
 'type': 'AN',
 'unitary_value': 55.34}
Javier Buzzi
  • 6,296
  • 36
  • 50