Search code examples
pythondictionarynestedlist-comprehension

in nested dictionary dynamically test if the value is a dictionary or a dictionary list


I iterate through a nested dictionary taken from a json including one of the keys ("price") and sometimes a list sometimes a dictionary.

Data={"main": {"sub_main": [   
    
{"id": "995", "item": "850", "price": {"ref": "razorback", "value": "250"}},
    
{"id": "953", "item": "763", "price": [{"ref": "razorback", "value": "450"},{"ref": "sumatra", "value": "370"},{"ref": "ligea", "value": "320"} ]}, 
    
]}}

I filter the result according to the value of another key ("id").

# here, the value of "price" key is a dict
result1 = [item["price"] for item in Data["main"]["sub_main"] if item["id"]=="995"]

# here, the value of "price" key is a list of dict
result2 = [item["price"] for item in Data["main"]["sub_main"] if item["id"]=="953"]

then I convert the result into a dictionary

#here I have what I wanted, because the "price" key is a dict

dresult={k:v for e in result1 for (k,v) in e.items()}

but when the "price" key has a dictionary list as its value, it doesn't work, because of course I get an error "'list' object has no attribute 'items'

#it cannot loop on the value and key because the "price" key is a list

dresult={k:v for e in result2 for (k,v) in e.items()}

how to make it convert the result to dictionary in both cases (because I'm iterating through thousands of data). how to dynamically do a type test and change to finally have a dictionary.I would like to use the result to display in a view in Django. I need it to be a dictionary

thank you.


Solution

  • I hope I've understood your question right. In this code I distinguish if item['price'] is dict/list and create a new dict from ref/value keys:

    Data = {
        "main": {
            "sub_main": [
                {
                    "id": "995",
                    "item": "850",
                    "price": {"ref": "razorback", "value": "250"},
                },
                {
                    "id": "953",
                    "item": "763",
                    "price": [
                        {"ref": "razorback", "value": "450"},
                        {"ref": "sumatra", "value": "370"},
                        {"ref": "ligea", "value": "320"},
                    ],
                },
            ]
        }
    }
    
    
    ids = "995", "953"
    
    for id_ in ids:
        out = {
            d["ref"]: d["value"]
            for item in Data["main"]["sub_main"]
            for d in (
                [item["price"]]
                if isinstance(item["price"], dict)
                else item["price"]
            )
            if item["id"] == id_
        }
        print(id_, out)
    

    Prints:

    995 {'razorback': '250'}
    953 {'razorback': '450', 'sumatra': '370', 'ligea': '320'}