Search code examples
pythonjsonindexingkey

Pulling info from JSON by Key value


I'm working with an API that sends JSON files in the following structure (and I'm trying to use the API in Python):

{
    "inventory": [
        {
            "ID": 10,
            "name": "Potion",
            "quantity": 20
        },
        {
            "ID": 15,
            "name": "Ether",
            "quantity": 12
        }
    ]
}

But with hundreds of items.

What I'm trying to do is find the quantity of a particular item, based on its unique 'ID' key's value. So I might be looking for the amount of Potions I have based on the ID '10', and I'm stumped as to how to do that.

I tried:

for key, value in inventory_data.items():
   if key["ID"] == 10:
      potion_index = index

To try to pull the index so I could then write a code snippet to pull by the index of where Potion falls in the inventory, but that didn't work.

Also - the list and order of the inventory changes, so I can't find the index just once and be good, I'd need to search each time.


Solution

  • Here is how you can get the quantity of item with ID == 10 or how you can remove the item (using list-comprehension):

    dct = {
        "inventory": [
            {"ID": 10, "name": "Potion", "quantity": 20},
            {"ID": 15, "name": "Ether", "quantity": 12},
        ]
    }
    
    # to get the quantity of item with 'ID' == 10:
    qnt = next(d["quantity"] for d in dct["inventory"] if d["ID"] == 10)
    print(qnt)
    

    Prints:

    20
    

    To remove dict with 'ID' == 10, use list-comprehension:

    dct["inventory"] = [d for d in dct["inventory"] if d["ID"] != 10]
    print(dct)
    

    Prints:

    {"inventory": [{"ID": 15, "name": "Ether", "quantity": 12}]}
    

    But I recommend to convert the inventory from list to dictionary:

    # convert the inventory to dictionary:
    dct["inventory"] = {d["ID"]: d for d in dct["inventory"]}
    
    # searching for item with ID == 10 is now key lookup:
    print(dct["inventory"][10]["quantity"])
    

    Prints:

    20