1

I'm trying to get the values of the first object's direction and station returned in this JSON, but I'm getting the following error

KeyError: 0

Here's my code:

print(json.dumps(savedrequest, indent=4))
savedstation = savedrequest[0]['station']
saveddirection = savedrequest[0]['direction']

And this is what it's returning in the print:

{
     "-bas": {
         "email_address": "dd3@gmail.com", 
         "direction": "Southbound", 
         "station": "place-har"
     }, 
     "-bus": {
         "email_address": "dd4@gmail.com", 
         "direction": "Southbound", 
         "station": "place-su"
     }
 }

I don't know what -bas or -bus is going to be when it gets returned, I need to select the first object in the array.

Tms91
  • 3,456
  • 6
  • 40
  • 74
beaconhill
  • 441
  • 6
  • 28
  • 1
    `savedrequest` isn't an array, it doesn't have a key `0`. You need to use `'-bas'` (or `'-bus'`). – gen_Eric Apr 14 '17 at 14:12
  • In that array, is there a way of selecting the first object and getting the values from those `direction` and `station` keys? – beaconhill Apr 14 '17 at 14:13
  • Why are you accessing key `0`? – Joel Cornett Apr 14 '17 at 14:13
  • You dont have list, so you need to use key: e.g. -bus. – Jan Giacomelli Apr 14 '17 at 14:13
  • I don't know what `-bas` or `-bus` is going to be, I just need to select the first object in the array – beaconhill Apr 14 '17 at 14:14
  • you should to use ```['-bas']['station']``` –  Apr 14 '17 at 14:15
  • 2
    There *is* no array. You have a JSON *object* that gets converted to a python *dict*. Dictionaries in python are inherently unordered, so there is no concept of a 'first' element – Joel Cornett Apr 14 '17 at 14:15
  • Where is this `savedrequest` object coming from? – gen_Eric Apr 14 '17 at 14:15
  • 1
    It's not an array, it's a dictionary. Dictionaries are not ordered, so you can't access them using [0], [1], etc. You can only access them by keys in the dictionary. There's no other way. – Munir Apr 14 '17 at 14:15
  • If you just want to get an arbitrary value out of the array, you can do something like: `savedrequest.popitem()[0]` or `savedrequest.values()[0]` – Joel Cornett Apr 14 '17 at 14:16
  • @JoelCornett I'm consistently getting this JSON back in the same order from a third party API. Is there a way at getting the first one in the group? – beaconhill Apr 14 '17 at 14:19
  • @RocketHazmat third party API call. – beaconhill Apr 14 '17 at 14:19
  • @beaconhill Even pure JSON objects are not guaranteed to be ordered so I would avoid depending on object ordering if at all possible. (ref: http://www.rfc-editor.org/rfc/rfc7159.txt, see section 1). – Joel Cornett Apr 14 '17 at 17:47

1 Answers1

4

Your JSON was decoded into an "object" (called a dict in python), it's not an array. As such, it has no particular "order". What you think is the "first" element may not actually be stored that way. There's no guarantee that the same object will be first each time.

What you could try, however, is to convert these dicts into OrderedDicts by using the object_pairs_hook parameter of json.loads (and json.load). An OrderedDict is like a dict, but it remembers the that order elements were inserted into it.

import json
from collections import OrderedDict

savedrequest = json.loads(data, object_pairs_hook=OrderedDict)

# Then you can get the "first" value as `OrderedDict` remembers order
#firstKey = next(iter(savedrequest))
first = next(iter(savedrequest.values()))

savedstation = first['station']
saveddirection = first['direction']

(This answer is thanks to https://stackoverflow.com/a/6921760 and https://stackoverflow.com/a/21067850)

Community
  • 1
  • 1
gen_Eric
  • 223,194
  • 41
  • 299
  • 337