Home > Enterprise >  How to select a certain key from a dictionary in a list of another list?
How to select a certain key from a dictionary in a list of another list?

Time:10-12

I have a nested JSON-file that looks like this:

[
   {
      "IsRecentlyVerified": true,
      "AddressInfo": {
          "Town": "Haarlem",
      },
      "Connections": [
          {
             "PowerKW": 17,
             "Quantity": 1
          }
       ],
       "NumberOfPoints": 1,
    },
    {
      "IsRecentlyVerified": true,
      "AddressInfo": {
          "Town": "Haarlem",
      },
      "Connections": [
          {
             "PowerKW": 17,
             "Quantity": 1
          },
          {
             "PowerKW": 17,
             "Quantity": 1
          }
       ],
       "NumberOfPoints": 1,
    }
]

As you can see, the list of this JSON-file consists of two dictionaries that each contains another list (= "Connections") that consists of at least one dictionary. In each dictionary of this JSON-file, I want to select all keys named "Quantity" to make a sum with its value (so in the example code above, I want to calculate that there are 3 Quantities in total).

Sometimes, the key "Quantity" is not always present, so that's why I used in to check if it is present. I noticed that it now only finds the key "Quantity" when I mention the index, like this: if "Quantity" in ev_list[info]["Connections"][0]

def amountOfChargingStations():
    totalAmountOfChargingPolesInCity = 0

    for info in range(len(ev_list)):
        if "Town" in ev_list[info]["AddressInfo"]:
            if ev_list[info]["AddressInfo"]["Town"] == "Haarlem":
                totalAmountOfChargingStationsInCity = totalAmountOfChargingStationsInCity   1

            if "Quantity" in ev_list[info]["Connections"][0]:
                if ev_list[info]["Connections"]:
                    for pole in ev_list[info]["Connections"]:
                        totalAmountOfChargingPolesInCity = totalAmountOfChargingPolesInCity   pole["Quantity"]
            else:
                print("Can't find connection")

    print("There are at least", totalAmountOfChargingPolesInCity, "charging poles available.")

polesAndStations = amountOfChargingStations()

The problem is that it now only uses the first dictionary of each "Connections"-list to make the sum. How can I select all keys named "Quantity" to make this sum, without knowing the total the amount of dictionaries in each "Connections"-list? (The total amount varies from 1 up to more than 10). Is there something like [0:end]?

CodePudding user response:

You can try recursion:

import json


def get_quantity(o):
    if isinstance(o, dict):
        if "Quantity" in o:
            yield o["Quantity"]
        for v in o.values():
            yield from get_quantity(v)
    elif isinstance(o, list):
        for v in o:
            yield from get_quantity(v)


with open("your_file.json", "r") as f_in:
    data = json.load(f_in)

print(sum(get_quantity(data)))

Prints:

3

CodePudding user response:

Here's a simple approach that, given the structure of your JSON as described, works as required:

quantity = 0

for d in json.loads(JDATA):
    if (_list := d.get('Connections')):
        for _d in _list:
            quantity  = _d.get('Quantity', 0)

print(quantity)

Output:

3

CodePudding user response:

as a oneliner:

total_quantity = sum([con['Quantity'] for dataset in data for con in dataset['Connections'] if 'Connections' in dataset.keys() and 'Quantity' in con.keys() ])

given datais your imported json.

CodePudding user response:

using jmespath you can get sum as

import jmespath
print(sum(jmespath.search("[*].Connections[].Quantity", data), 0))
  • Related