3

I am using an Python API Wrapper to get a JSON response of car models. Depending on the car searched, I could get 0 to 50 'ID' results. How can extract the first occurrence of ID from my string yet ignore all the others?

API Wrapper (from GitHub):

# Make API Call
   ....
   ....
# extract JSON
    try:
        response_json = r.json()
        print response_json

I've done some searching but most of the solutions I see are quite complicated. Splitting strings, iterating through, converting that back to a print statement. Any easier way to search_mystring('id') if you will?

My String (response_json):

{u'styles': [{u'trim': u'EX', u'name': u'EX 4dr Sedan (2.3L 4cyl 4A)', u'make':
{u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 100001210,
u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u
'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan', u'm
odelName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'EX', u'name': u
'EX 2dr Coupe w/Leather (2.3L 4cyl 5M)', u'make': {u'id': 200001444, u'niceName'
: u'honda', u'name': u'Honda'}, u'id': 100001209, u'year': {u'id': 100000126, u'
year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name'
: u'Accord'}, u'submodel': {u'body': u'Coupe', u'modelName': u'Accord Coupe', u'
niceName': u'coupe'}}, {u'trim': u'EX', u'name': u'EX 4dr Sedan w/Leather (2.3L
4cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}
, u'id': 100001212, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id'
: u'Honda_Accord', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'
body': u'Sedan', u'modelName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim
': u'EX', u'name': u'EX 4dr Sedan (2.3L 4cyl 5M)', u'make': {u'id': 200001444, u
'niceName': u'honda', u'name': u'Honda'}, u'id': 100001211, u'year': {u'id': 100
000126, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord
', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan', u'modelName': u'Accord
Sedan', u'niceName': u'sedan'}}, {u'trim': u'EX V-6', u'name': u'EX V-6 2dr Coup
e (3.0L 6cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'honda', u'name': u
'Honda'}, u'id': 100001214, u'year': {u'id': 100000126, u'year': 2001}, u'model'
: {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'Accord'}, u'submod
el': {u'body': u'Coupe', u'modelName': u'Accord Coupe', u'niceName': u'coupe'}},
 {u'trim': u'EX', u'name': u'EX 4dr Sedan w/Leather (2.3L 4cyl 5M)', u'make': {u
'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 100001213, u'
year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'n
iceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan', u'mod
elName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'LX', u'name': u'L
X 2dr Coupe (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'honda',
u'name': u'Honda'}, u'id': 100001216, u'year': {u'id': 100000126, u'year': 2001}
, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'Accord'}
, u'submodel': {u'body': u'Coupe', u'modelName': u'Accord Coupe', u'niceName': u
'coupe'}}, {u'trim': u'EX V-6', u'name': u'EX V-6 4dr Sedan (3.0L 6cyl 4A)', u'm
ake': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 10000
1215, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Acco
rd', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan
', u'modelName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'EX', u'na
me': u'EX 2dr Coupe (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'
honda', u'name': u'Honda'}, u'id': 100002024, u'year': {u'id': 100000126, u'year
': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'
Accord'}, u'submodel': {u'body': u'Coupe', u'modelName': u'Accord Coupe', u'nice
Name': u'coupe'}}, {u'trim': u'DX', u'name': u'DX 4dr Sedan (2.3L 4cyl 5M)', u'm
ake': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 10000
1204, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Acco
rd', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan
', u'modelName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'DX', u'na
me': u'DX 4dr Sedan (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'
honda', u'name': u'Honda'}, u'id': 100001203, u'year': {u'id': 100000126, u'year
': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'
Accord'}, u'submodel': {u'body': u'Sedan', u'modelName': u'Accord Sedan', u'nice
Name': u'sedan'}}, {u'trim': u'DX', u'name': u'DX 4dr Sedan w/Side Airbags (2.3L
 4cyl 5M)', u'make': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'
}, u'id': 100001206, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id
': u'Honda_Accord', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u
'body': u'Sedan', u'modelName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'tri
m': u'DX', u'name': u'DX 4dr Sedan w/Side Airbags (2.3L 4cyl 4A)', u'make': {u'i
d': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 100001205, u'ye
ar': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'nic
eName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan', u'model
Name': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'EX', u'name': u'EX
2dr Coupe w/Leather (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'
honda', u'name': u'Honda'}, u'id': 100001208, u'year': {u'id': 100000126, u'year
': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'
Accord'}, u'submodel': {u'body': u'Coupe', u'modelName': u'Accord Coupe', u'nice
Name': u'coupe'}}, {u'trim': u'EX', u'name': u'EX 2dr Coupe (2.3L 4cyl 5M)', u'm
ake': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 10000
1207, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Acco
rd', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Coupe
', u'modelName': u'Accord Coupe', u'niceName': u'coupe'}}, {u'trim': u'LX V-6',
u'name': u'LX V-6 4dr Sedan (3.0L 6cyl 4A)', u'make': {u'id': 200001444, u'niceN
ame': u'honda', u'name': u'Honda'}, u'id': 100001227, u'year': {u'id': 100000126
, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'n
ame': u'Accord'}, u'submodel': {u'body': u'Sedan', u'modelName': u'Accord Sedan'
, u'niceName': u'sedan'}}, {u'trim': u'Value Package', u'name': u'Value Package
4dr Sedan (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'honda', u'
name': u'Honda'}, u'id': 100001228, u'year': {u'id': 100000126, u'year': 2001},
u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'Accord'},
u'submodel': {u'body': u'Sedan', u'modelName': u'Accord Sedan', u'niceName': u's
edan'}}, {u'trim': u'LX', u'name': u'LX 4dr Sedan w/Side Airbags (2.3L 4cyl 5M)'
, u'make': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id':
100001225, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda
_Accord', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'
Sedan', u'modelName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'LX V
-6', u'name': u'LX V-6 2dr Coupe (3.0L 6cyl 4A)', u'make': {u'id': 200001444, u'
niceName': u'honda', u'name': u'Honda'}, u'id': 100001226, u'year': {u'id': 1000
00126, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord'
, u'name': u'Accord'}, u'submodel': {u'body': u'Coupe', u'modelName': u'Accord C
oupe', u'niceName': u'coupe'}}, {u'trim': u'Value Package', u'name': u'Value Pac
kage 4dr Sedan w/Side Airbags (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'nic
eName': u'honda', u'name': u'Honda'}, u'id': 100001229, u'year': {u'id': 1000001
26, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u
'name': u'Accord'}, u'submodel': {u'body': u'Sedan', u'modelName': u'Accord Seda
n', u'niceName': u'sedan'}}, {u'trim': u'LX', u'name': u'LX 2dr Coupe w/Side Air
bags (2.3L 4cyl 5M)', u'make': {u'id': 200001444, u'niceName': u'honda', u'name'
: u'Honda'}, u'id': 100001219, u'year': {u'id': 100000126, u'year': 2001}, u'mod
el': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'Accord'}, u'sub
model': {u'body': u'Coupe', u'modelName': u'Accord Coupe', u'niceName': u'coupe'
}}, {u'trim': u'LX', u'name': u'LX 4dr Sedan (2.3L 4cyl 4A)', u'make': {u'id': 2
00001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 100001220, u'year':
{u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName
': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan', u'modelName'
: u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'LX', u'name': u'LX 2dr C
oupe (2.3L 4cyl 5M)', u'make': {u'id': 200001444, u'niceName': u'honda', u'name'
: u'Honda'}, u'id': 100001217, u'year': {u'id': 100000126, u'year': 2001}, u'mod
el': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'Accord'}, u'sub
model': {u'body': u'Coupe', u'modelName': u'Accord Coupe', u'niceName': u'coupe'
}}, {u'trim': u'LX', u'name': u'LX 2dr Coupe w/Side Airbags (2.3L 4cyl 4A)', u'm
ake': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 10000
1218, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Acco
rd', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Coupe
', u'modelName': u'Accord Coupe', u'niceName': u'coupe'}}, {u'trim': u'LX', u'na
me': u'LX 4dr Sedan w/ABS and Side Airbags (2.3L 4cyl 4A)', u'make': {u'id': 200
001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 100001223, u'year': {u
'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName':
 u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan', u'modelName':
u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'LX', u'name': u'LX 4dr Sed
an w/Side Airbags (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'niceName': u'ho
nda', u'name': u'Honda'}, u'id': 100001224, u'year': {u'id': 100000126, u'year':
 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name': u'Ac
cord'}, u'submodel': {u'body': u'Sedan', u'modelName': u'Accord Sedan', u'niceNa
me': u'sedan'}}, {u'trim': u'LX', u'name': u'LX 4dr Sedan (2.3L 4cyl 5M)', u'mak
e': {u'id': 200001444, u'niceName': u'honda', u'name': u'Honda'}, u'id': 1000012
21, u'year': {u'id': 100000126, u'year': 2001}, u'model': {u'id': u'Honda_Accord
', u'niceName': u'accord', u'name': u'Accord'}, u'submodel': {u'body': u'Sedan',
 u'modelName': u'Accord Sedan', u'niceName': u'sedan'}}, {u'trim': u'LX', u'name
': u'LX 4dr Sedan w/ABS (2.3L 4cyl 4A)', u'make': {u'id': 200001444, u'niceName'
: u'honda', u'name': u'Honda'}, u'id': 100001222, u'year': {u'id': 100000126, u'
year': 2001}, u'model': {u'id': u'Honda_Accord', u'niceName': u'accord', u'name'
: u'Accord'}, u'submodel': {u'body': u'Sedan', u'modelName': u'Accord Sedan', u'
niceName': u'sedan'}}], u'stylesCount': 28}

Ideally, I'd like access to a 'styleID' variable in the end that would be equal to '200001444' in this case.

Fairplay89
  • 147
  • 3
  • 15
  • Here's an example of what I was reviewing: http://stackoverflow.com/questions/11339210/how-to-get-integer-values-from-a-string-in-python – Fairplay89 May 14 '15 at 04:28
  • ok, you have example input but no example output. what is your target output given this input? – Tom McClure May 14 '15 at 04:36
  • They're stored in a dictionary, which means they're not sorted. If you pull out the first one you find, it probably won't be the first one that was in the JSON. – Mark Ransom May 14 '15 at 04:36
  • What you've got there is a representation of a Python dictionary. It's *not* JSON, although it might well have been constructed from a JSON document. How did you get that? I think there's a pretty good chance you've made a mistake somewhere, and a sensible answer would depend on knowing what that mistake was. – Zero Piraeus May 14 '15 at 04:43
  • The API returns a JSON response, which is then converted to the above. Ideally, the output would be a variable that holds '200001444' in this case. – Fairplay89 May 14 '15 at 04:47
  • After executing the API call, the wrapper sets response_json = r.json(). response_json contains the string/dictionary/old json listed above. – Fairplay89 May 14 '15 at 04:48
  • It would be a lot easier to deal with the actual JSON response than with a string representation of a Python dictionary constructed from that JSON response (which has then apparently had linebreaks arbitrarily inserted into it). Can you get at the original JSON? – Zero Piraeus May 14 '15 at 04:50
  • In my code, I call the API endpoint and then I have this in the wrapper (code not written by me): # extract JSON try: response_json = r.json(). I am guessing that I want to use r.json(), not response_json which is the string I shared above. Correct? – Fairplay89 May 14 '15 at 04:52
  • You're using [`requests`](http://docs.python-requests.org/en/latest/), right? If so, `r.json()` will be giving you a dict, not a string representation of one, and things are much easier. – Zero Piraeus May 14 '15 at 04:57

3 Answers3

7

What you've got is not a string, but a dictionary returned by the Requests library's response.json() method.

Here's what response_json actually looks like:

{
    'styles': [
        {
            'id': 100001210,
            'make': { 'id': 200001444, 'name': 'Honda', 'niceName': 'honda'},
            'model': { 'id': 'Honda_Accord', 'name': 'Accord', 'niceName': 'accord'},
            'name': 'EX 4dr Sedan (2.3L 4cyl 4A)',
            'submodel': { 'body': 'Sedan', 'modelName': 'Accord Sedan', 'niceName': 'sedan'},
            'trim': 'EX',
            'year': {'id': 100000126, 'year': 2001}},
        {
            'id': 100001209,
            'make': {'id': 200001444, 'name': 'Honda', 'niceName': 'honda'},
            'model': {'id': 'Honda_Accord',
            'name': 'Accord',
            'niceName': 'accord'},
            'name': 'EX 2dr Coupe w/Leather (2.3L 4cyl 5M)',
            'submodel': {'body': 'Coupe', 'modelName': 'Accord Coupe', 'niceName': 'coupe'},
            'trim': 'EX',
            'year': {'id': 100000126, 'year': 2001}
        },
        # ...
    ],
    'stylesCount': 28
}

... so, all you actually need is the value of the id key of the first dictionary in the list attached to the styles key:

>>> response_json['styles'][0]['id']
100001210

... or if, as you suggest, you want the Make ID:

>>> response_json['styles'][0]['make']['id']
200001444
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
4

Use the JSON library to load the string into a variable, and then reference the fields directly:

import json
data = json.loads(my_string)
data['styles'][0]['id']

If the data is already in a structure (as it appears above), then

response_json['styles'][0]['id']

should give you the first id.

Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
  • Woohoo! response_json['styles'][0]['id'] gets me what I need. Thank you! :) – Fairplay89 May 14 '15 at 05:08
  • While the second part of your answer is correct, the first is not: even if OP had been correct in thinking that they had a string, the string described is not JSON, and `json.loads()` would have resulted in a `ValueError`. – Zero Piraeus May 14 '15 at 05:30
  • True, but the technique still works. If a real JSON string was received, json.loads() would load it. The string he showed was the output of a dict, which made me realize that it was already loaded. – Brent Washburne May 14 '15 at 05:39
0

There are multiple IDs in the string, but assuming you want the ID of the first car make:

import ast
# s is the string in the question literally
print ast.literal_eval(s.replace('\n', ''))['styles'][0]['make']['id']

Output:

200001444

Edit: If the input is already the dict, then you could try:

s['styles'][0]['make']['id']
YS-L
  • 14,358
  • 3
  • 47
  • 58
  • I have the following: 'json_response = api.make_call(endpoint) styleID = ast.literal_eval(json_response.replace('\n', ''))['styles'][0]['make']['id'] print styleID' and get dict object has no attribute replace – Fairplay89 May 14 '15 at 05:02
  • Is the input already the dictionary that ``ast.literal_eval`` above is trying to create? If so, the edit might help. – YS-L May 14 '15 at 05:08