Python: How to access list object deep within a nested dictionary structure?

Question:

I have a rather deep python nested array(converted from XML for ease in processing) that has a list within a bunch of dictionaries. I need to access the list object (which should be ‘Apparatus’) so I can do a number of manipulations. A) Count the current number of list objects so I can add another; B) Change some of the items within the dictionaries within the list objects. But I can’t seem to tease out the syntax to let me access the list item(s). (After I figure it out, I’ll need to do similar tasks on the more deeply nested "ApparatusPersonnel").

Here’s the Dictionary Structure (whose format I don’t dictate, nor can I alter, since I have to unparse it back to xml to be consumed by a program outside of my control).

`

{ 'CadData': { 'EmsIncidentCollection': { 'EmsIncident': { 'AgencyNumber': '222222',
                                                           'ZoneNumber': '30'}},
               'FireIncidentCollection': { 'FireIncident': { 'AgencyNumber': '222222',
                                                             'Alarm': '2014-02-02T02:23:22-06:00',
                                                             'AlarmType': 'TypeofAlarm_SingleStation',
                                                             'ApartmentNumber': '4',
                                                             'ApparatusCollection': { 'Apparatus': [ { 'ApparatusPersonnelCollection': { 'ApparatusPersonnel': [ { 'FirstName': 'Jon',
                                                                                                                                                                   'LastName': 'Snow',
                                                                                                                                                                   'Level': 'PersonnelLevel_FirefighterI',
                                                                                                                                                                   'LicenseNumber': '1234',
                                                                                                                                                                   'Rank': 'Captain',
                                                                                                                                                                   'Role': 'PersonnelRole_Driver',
                                                                                                                                                                   'TimeIn': '2014-02-02T02:16:23-06:00',
                                                                                                                                                                   'TimeOut': '2014-02-02T02:22:23-06:00'},
                                                                                                                                                                 { 'LicenseNumber': '1138'}]},
                                                                                                       'Arrival': '2014-02-02T02:18:22-06:00',
                                                                                                       'Clear': '2014-02-02T02:19:22-06:00',
                                                                                                       'Dispatch': '2014-02-02T02:16:22-06:00',
                                                                                                       'Enroute': '2014-02-02T02:17:22-06:00',
                                                                                                       'InService': '2014-02-02T02:20:22-06:00',
                                                                                                       'Number': 'AM22'},
                                                                                                     { 'Number': 'EM11'}]},
                                                             'Arrival': '2014-02-02T02:24:22-06:00',
                                                             'CadID': '0200222',
                                                             'CityName': 'Lakeville',
                                                             'Controlled': '2014-02-02T02:25:22-06:00',
                                                             'CountyName': 'Dakota',
                                                             'CrossStreet': None,
                                                             'District': None,
                                                             'Fdid': '123',
                                                             'InService': '2014-02-02T02:27:22-06:00',
                                                             'IncidentDate': '2014-02-02T02:21:22-06:00',
                                                             'IncidentNumber': '0200222',
                                                             'LastUnitCleared': '2014-02-02T02:26:22-06:00',
                                                             'Latitude': '44.6550598',
                                                             'Longitude': '-93.2710266',
                                                             'MixUseProperty': 'MixedUseProperty_IndustrialUse',
                                                             'Narrative': 'This '
                                                                          'is '
                                                                          'a '
                                                                          'test '
                                                                          'narrative.',
                                                             'Psap': '2014-02-02T02:22:22-06:00',
                                                             'Shift': 'A',
                                                             'StateName': 'MN',
                                                             'Station': 'Test '
                                                                        'Station',
                                                             'StreetName': 'Fake',
                                                             'StreetNumber': '123',
                                                             'StreetPrefix': 'N',
                                                             'StreetSuffix': 'N',
                                                             'StreetType': 'ST',
                                                             'ZipCode': '55044',
                                                             'ZoneNumber': '2B'}}}}

`

I have tried to access the list this way:

`

for key in my_dict['CadData']['FireIncidentCollection']['FireIncident']['ApparatusCollection']:
    print(key)
    print(type(key))
    print(len(key))

`

It’s putting me in the right spot, but telling me it’s a Str:

Apparatus
<class 'str'>
9

Iterating over the next layer down gives me only the Dictionary object below:

`

for key in my_dict['CadData']['FireIncidentCollection']['FireIncident']['ApparatusCollection']['Apparatus']:
    print(key)
    print(type(key))
    print(len(key))

`

{'Number': 'AM22', 'Dispatch': '2014-02-02T02:16:22-06:00', 'Enroute': '2014-02-02T02:17:22-06:00', 'Arrival': '2014-02-02T02:18:22-06:00', 'Clear': '2014-02-02T02:19:22-06:00', 'InService': '2014-02-02T02:20:22-06:00', 'ApparatusPersonnelCollection': {'ApparatusPersonnel': [{'LicenseNumber': '1234', 'Level': 'PersonnelLevel_FirefighterI', 'Role': 'PersonnelRole_Driver', 'FirstName': 'Jon', 'LastName': 'Snow', 'TimeIn': '2014-02-02T02:16:23-06:00', 'TimeOut': '2014-02-02T02:22:23-06:00', 'Rank': 'Captain'}, {'LicenseNumber': '1138'}]}}
<class 'dict'>
7
{'Number': 'EM11'}
<class 'dict'>
1

I want to be able to get the length of the list (2 in the sample data) so I can access the list items directly and have an index value to add another (so I would add ….[Apparatus][2].

How can I do that? And, am I going about this poorly, accessing the elements directly by the known element names? Thanks.

Asked By: buckyswider

||

Answers:

Your desired list can be obtained like this:

desired_list = my_dict['CadData']['FireIncidentCollection']['FireIncident']['ApparatusCollection']['Apparatus']

Trying print (desired_list) returns:

[{'ApparatusPersonnelCollection': {'ApparatusPersonnel': [{'FirstName': 'Jon',
     'LastName': 'Snow',
     'Level': 'PersonnelLevel_FirefighterI',
     'LicenseNumber': '1234',
     'Rank': 'Captain',
     'Role': 'PersonnelRole_Driver',
     'TimeIn': '2014-02-02T02:16:23-06:00',
     'TimeOut': '2014-02-02T02:22:23-06:00'},
    {'LicenseNumber': '1138'}]},
  'Arrival': '2014-02-02T02:18:22-06:00',
  'Clear': '2014-02-02T02:19:22-06:00',
  'Dispatch': '2014-02-02T02:16:22-06:00',
  'Enroute': '2014-02-02T02:17:22-06:00',
  'InService': '2014-02-02T02:20:22-06:00',
  'Number': 'AM22'},
 {'Number': 'EM11'}]

Which is the list you’re trying to get a hold of, yes? If you wanted the length, you’d simply try len(desired_list), which as you wanted, returns 2.

As for whether you’re going about this poorly by accessing content directly using known key names – that depends on whether your data is always organised this way, so that your target information is always identifiable by the same keys. If this isn’t the case, then there has to be some other reliable means by which to identify your data. I guess the answer to your latter question depends on what your overall data set does (and might, if it’s changeable) look like.

Answered By: Vin