0

I am fairly new to Python and have been working on trying to print out the values attached to a key which is present in a nested list of dictionaries in a JSON. Here is the structure from what I can tell:

details - List of dicts

scorecardDetails - List of dicts

scorecard - Dict

playerHandicap - Key:Value

It is also worth noting there is another list called 'summary' at the same level as 'details'.

This is where I am at currently, but am struggling to work out how to identify that I only want to look at the 'playerHandicap' key:

details_list = json_load['details']

for index in range(len(details_list)):
    for key in details_list[index]:
        print(details_list[index][key])

Here is a snapshot of the JSON (the key/value pair required is in the 'scorecard' dict which there is multiple of):

"details":[
      {
         "startTime":"2021-03-16T12:16:16.000Z",
         "formattedStartTime":"2021-03-16T12:16:16Z",
         "scorecardDetails":[
            {
               "scorecard":{
                  "id":172482642,
                  "customerId":"******",
                  "playerProfileId":*****,
                  "roundPlayerName":"*******",
                  "connectDisplayName":"********",
                  "courseGlobalId":21042,
                  "courseSnapshotId":43716,
                  "frontNineGlobalCourseId":21042,
                  "scoreType":"STROKE_PLAY",
                  "useHandicapScoring":true,
                  "useStrokeCounting":false,
                  "startTime":"2021-03-16T12:16:16.000Z",
                  "formattedStartTime":"2021-03-16T12:16:16Z",
                  "endTime":"2021-04-23T09:09:47.000Z",
                  "formattedEndTime":"2021-04-23T09:09:47Z",
                  "unitId":"1",
                  "roundType":"ALL",
                  "inProgress":false,
                  "excludeFromStats":false,
                  "holesCompleted":18,
                  "publicRound":false,
                  "score":29,
                  "playerHandicap":0,
                  "courseHandicapStr":"061018120208141604010709111517031305",
                  "teeBox":"null",
                  "handicapType":"MEN",
                  "teeBoxRating":73.03,
                  "teeBoxSlope":118,
                  "lastModifiedDt":"2021-04-23T09:09:46.000Z",
                  "sensorOnPutter":false,
                  "handicappedStrokes":101,
                  "strokes":101,

I'm sure it's an easy solution but struggling to get my head around the different levels of looping! Thanks :)

GregCet
  • 5
  • 3
  • Note that "JSON" is a data format, and is text. When JSON data is loaded, you get native data types, not "a JSON". – outis May 09 '22 at 19:08
  • Does this answer your question? [Python Accessing Nested JSON Data](//stackoverflow.com/q/23306653/90527) – outis May 09 '22 at 19:29

3 Answers3

1

The following code will help you

for item in json_load['details']:
    for scorecardDetail in item['scorecardDetails']:
        if 'playerHandicap' in scorecardDetail['scorecard']: 
            print(scorecardDetail['scorecard']['playerHandicap'])
Balaji Kanagaraju
  • 558
  • 1
  • 6
  • 10
  • Ah great, this kind of works. It does throw a KeyError at the the 12th result out or 51 though: print(scorecardDetail['scorecard']['playerHandicap']) KeyError: 'playerHandicap' – GregCet May 09 '22 at 08:45
  • It means the key 'playerHandicap' is not present in some of the objects. You can simply have a check. I have updated my answer with the check – Balaji Kanagaraju May 09 '22 at 09:45
  • +1 - was writing this exact answer when it appeared! For missing values you could also used a `try`/`except` statement to deal with `KeyError`s and have the except print "n/a". Or just add an `else:` to this answer. – Dave May 09 '22 at 12:35
0

I am not sure to understand your question.

You can use dict.keys() to get all the keys in a dictionary.

Here is a response maybe : https://stackoverflow.com/a/7002449/19074450

dict_test = {"details":[
      {
         "startTime":"2021-03-16T12:16:16.000Z",
         "formattedStartTime":"2021-03-16T12:16:16Z",
         "scorecardDetails":[
            {
               "scorecard":{
                  "id":172482642,
                  "customerId":"6300102921355894",
                  "playerProfileId":62337607,
                  "roundPlayerName":"*******",
                  "connectDisplayName":"5536cd4a-f35e-4034-966c-a5d8238a8c26",
                  "courseGlobalId":21042,
                  "courseSnapshotId":43716,
                  "frontNineGlobalCourseId":21042,
                  "scoreType":"STROKE_PLAY",
                  "useHandicapScoring":True,
                  "useStrokeCounting":False,
                  "startTime":"2021-03-16T12:16:16.000Z",
                  "formattedStartTime":"2021-03-16T12:16:16Z",
                  "endTime":"2021-04-23T09:09:47.000Z",
                  "formattedEndTime":"2021-04-23T09:09:47Z",
                  "unitId":"1",
                  "roundType":"ALL",
                  "inProgress":False,
                  "excludeFromStats":False,
                  "holesCompleted":18,
                  "publicRound":False,
                  "score":29,
                  "playerHandicap":0}}]}]}
                  
details_list = dict_test['details']

for index in details_list:
    for dict_ in details_list:
        for key_ in dict_.keys():
            print(dict_[key_])
GregCet
  • 5
  • 3
0

The elegant solution will be to use jmespath Also it will also handle the cases where key doesnot exist

pip install jmespath

If you have data as correct dictionary then we can use

import jmespath
expression = jmespath.compile('details[*].scorecardDetails[*].scorecard.playerHandicap')
# this expression will look in each detail then each scorecardDetails then in each scorecard it will fetch playerHandicap
res = expression.search(data)
print(res)  # this will print the list of values from all records
Deepak Tripathi
  • 3,175
  • 1
  • 8
  • 21