I have a JSON string that i got into python that looks something like this:
{"count": 100,
"facets": null,
"previous_page": null,
"results": [{"updated_at": "2013-09-17T13:45:13Z", "test_id": 194037042, "customer_id":
203793326, "id": 1954182}]
There are more elements but this is a small cut of what i need. Basically, results has a list of 100 dictionaries that contain the elements above "updated_at, test_id, customer_id, id" What i need to do is the following:
I need to get a list of all of the values of JUST the id. I am not sure how to go about this though, i have tried doing things like:
for i in my_dict['results']:
print i['id']
but i get an error message that says:
print i['id']
TypeError: string indices must be integers
What am i doing wrong?
You are not doing anything obviously wrong. Your data includes 'null' elements which are not proper python. This works fine.
my_dict = {"count": 100,
"facets": None,
"previous_page": None,
"results": [{"updated_at": "2013-09-17T13:45:13Z", "test_id": 194037042, "customer_id": 203793326, "id": 1954182}]
}
for i in my_dict['results']:
print i['id']
The error you have implies that one of your list items is a string and when you are trying to get the ['id'] element the error rightly tells you that list indices (a string is a list of characters) must be integers.
It looks like you haven't loaded the json into Python with json.loads(json_string)
And even after you do that, your "results" dict is actually going to be a list of dicts.
Try this:
import json
json_str = '{"count": 100, "facets": null, "previous_page": null, "results": [{"updated_at": "2013-09-17T13:45:13Z", "test_id": 194037042, "customer_id": 203793326, "id": 1954182}, {"updated_at": "2013-09-18T13:45:13Z", "test_id": 194037043, "customer_id": 203793327, "id": 1954183}]}'
data = json.loads(json_str)
result_ids = [result['id'] for result in data['results'] if 'id' in result]
Output:
[1954182, 1954183]
This code would then output a list containing 1954182 and 1954183.
Use a list comprehension here for greater speed and less lines of code. It also ensures that the result dict has an 'id' attribute before trying to access it.
Related
I have a JSON file like this:
print(resp)
dataList = []
{
"totalCount": 9812,
"pageSize": 50,
"nextPageKey": "12345",
"problems": [
{
"problemId": "1234",
"displayId": "test1",
"title": "host memory saturation",
"impactLevel": "INFRASTRUCTURE",
"severityLevel": "RESOURCE_CONTENTION",
"status": "OPEN"
}
]
}
I need to extract "title", "impactLevel" and "severityLevel" and create a data frame out this:
I have tried this:
dataList.append([resp['problems'][0]['title']['impactLevel']['severityLevel']])
hyperEntitydf = pd.DataFrame(dataList, columns=['Alert','Type','Severity'])
hyperEntitydf=hyperEntitydf.drop_duplicates()
print(hyperEntitydf.head())
On this line:
dataList.append([resp['problems'][0]['title']['impactLevel']['severityLevel']])
I am getting this error:
TypeError: string indices must be integers
Is it possible to extract multiple fields with one call?
dataList.append([resp['problems'][0]['title']['impactLevel']['severityLevel']])
No, it's not possible. For this to work, the json would need to be nested such that impactLevel were within title, and severityLevel were within impactLevel.
I'd suggest
x = resp['problems'][0]
dataList.append([x['title'], x['impactLevel', x['severityLevel'])
Unless, you want all the fields of the json, in which case you can do:
dataList.append(list(resp['problems'][0].values()))
Use operators.itemgetter:
from operator import itemgetter
f = itemgetter('title', 'impactLevel', 'severityLevel')
dataList.append(list(f(resp['problems'][0])))
You only need to use list if you specifically need a list; f will return a tuple.
If you want the three values from every element of resp['problems'],
dataList = list(map(f, resp['problems']))
Here, you only need list if DataFrame requires a list, rather than an arbitrary iterable.
I am running a method which returns a dictionary which is formed like the following :
{
"intents": [
{
"name": "goodbye",
"created": "2017-08-18T18:09:36.155Z",
"updated": "2017-08-18T18:09:41.755Z",
"description": null
},
{
"name": "hello",
"created": "2017-08-18T18:05:48.153Z",
"updated": "2017-08-18T18:06:06.004Z",
"description": null
}
],
"pagination": {
"refresh_url": "/v1/workspaces/9978a49e-ea89-4493-b33d-82298d3db20d/intents?version=2017-08-21"
}
}
This is all saved in a variable called response, which contains the dictionary for over 200 values.
If I print just "response", it prints all of the above, including "created/updated/description". I just want to print out the name value...and I cannot figure out how to do it.
I have read some posts here and tried the following -
for value in response:
print(value['intent'])
but similarly, this prints out everything (including description/update date etc).
How can I make it only print out the name?
And for a bonus, how can I add the list of names into an array which I can then iterate over?
It appears you want to access the name attribute of each sub-dict in intents. This should work -
for d in response['intents']:
print(d['name'])
If you want this stored in a list, use a list comprehension:
names = [d['name'] for d in response['intents']]
Adding names into list and print it:
names = [intent["name"] for intent in response["intents"]]
print(*names, sep='\n')
Have a look at my solution
names_list = []
for x in response["intents"]:
print x["name"] # it will print all of your names
names_list.append(x["name"]) # it will add the names into the names_list
print names_list
Hope it will help you :)
I have JSON output as follows:
{
"service": [{
"name": ["Production"],
"id": ["256212"]
}, {
"name": ["Non-Production"],
"id": ["256213"]
}]
}
I wish to find all ID's where the pair contains "Non-Production" as a name.
I was thinking along the lines of running a loop to check, something like this:
data = json.load(urllib2.urlopen(URL))
for key, value in data.iteritems():
if "Non-Production" in key[value]: print key[value]
However, I can't seem to get the name and ID from the "service" tree, it returns:
if "Non-Production" in key[value]: print key[value]
TypeError: string indices must be integers
Assumptions:
The JSON is in a fixed format, this can't be changed
I do not have root access, and unable to install any additional packages
Essentially the goal is to obtain a list of ID's of non production "services" in the most optimal way.
Here you go:
data = {
"service": [
{"name": ["Production"],
"id": ["256212"]
},
{"name": ["Non-Production"],
"id": ["256213"]}
]
}
for item in data["service"]:
if "Non-Production" in item["name"]:
print(item["id"])
Whatever I see JSON I think about functionnal programming ! Anyone else ?!
I think it is a better idea if you use function like concat or flat, filter and reduce, etc.
Egg one liner:
[s.get('id', [0])[0] for s in filter(lambda srv : "Non-Production" not in srv.get('name', []), data.get('service', {}))]
EDIT:
I updated the code, even if data = {}, the result will be [] an empty id list.
I have a json response from an API in this way:-
{
"meta": {
"code": 200
},
"data": {
"username": "luxury_mpan",
"bio": "Recruitment Agents👑👑👑👑\nThe most powerful manufacturers,\nwe have the best quality.\n📱Wechat:13255996580💜💜\n📱Whatsapp:+8618820784535",
"website": "",
"profile_picture": "https://scontent.cdninstagram.com/t51.2885-19/10895140_395629273936966_528329141_a.jpg",
"full_name": "Mpan",
"counts": {
"media": 17774,
"followed_by": 7982,
"follows": 7264
},
"id": "1552277710"
}
}
I want to fetch the data in "media", "followed_by" and "follows" and store it in three different lists as shown in the below code:--
for r in range(1,5):
var=r,st.cell(row=r,column=3).value
xy=var[1]
ij=str(xy)
myopener=Myopener()
url=myopener.open('https://api.instagram.com/v1/users/'+ij+'/?access_token=641567093.1fb234f.a0ffbe574e844e1c818145097050cf33')
beta=json.load(url)
for item in beta['data']:
list1.append(item['media'])
list2.append(item['followed_by'])
list3.append(item['follows'])
When I run it, it shows the error TypeError: string indices must be integers
How would my loop change in order to fetch the above mentioned values?
Also, Asking out of curiosity:- Is there any way to fetch the Watzapp no from the "BIO" key in data dictionary?
I have referred questions similar to this and still did not get my answer. Please help!
beta['data'] is a dictionary object. When you iterate over it with for item in beta['data'], the values taken by item will be the keys of the dictionary: "username", "bio", etc.
So then when you ask for, e.g., item['media'] it's like asking for "username"['media'], which of course doesn't make any sense.
It isn't quite clear what it is that you want: is it just the stuff inside counts? If so, then instead of for item in beta['data']: you could just say item = beta['data']['counts'], and then item['media'] etc. will be the values you want.
As to your secondary question: I suggest looking into regular expressions.
I am learning to use Python and APIs (specifically, this World Cup API, http://www.kimonolabs.com/worldcup/explorer)
The JSON data looks like this:
[
{
"firstName": "Nicolas Alexis Julio",
"lastName": "N'Koulou N'Doubena",
"nickname": "N. N'Koulou",
"assists": 0,
"clubId": "5AF524A1-830C-4D75-8C54-2D0BA1F9BE33",
"teamId": "DF25ABB8-37EB-4C2A-8B6C-BDA53BF5A74D",
"id": "D9AD1E6D-4253-4B88-BB78-0F43E02AF016",
"type": "Player"
},
{
"firstName": "Alexandre Dimitri",
"lastName": "Song-Billong",
"nickname": "A. Song",
"clubId": "35BCEEAF-37D3-4685-83C4-DDCA504E0653",
"teamId": "DF25ABB8-37EB-4C2A-8B6C-BDA53BF5A74D",
"id": "A84540B7-37B6-416F-8C4D-8EAD55D113D9",
"type": "Player"
},
]
I am simply trying to print all of the firstNames in this API. Here's what I have:
import urllib2
import json
url = "http://worldcup.kimonolabs.com/api/players?apikey=xxx"
json_obj = urllib2.urlopen(url).read
readable_json = json.dumps(json_obj)
playerstuff = readable_json['firstName']
for i in playerstuff:
print i['firstName']
But when I run it, I get the error "...line 8, in ...TypeError: list indices must be integers, not str"
I have looked around for solutions, but seem to find questions to more "in depth" API questions and I don't really understand it all yet, so any help or explanation as to what I need to do would be amazing. Thank you!
I solved changing
readable_json['firstName']
by
readable_json[0]['firstName']
First of all, you should be using json.loads, not json.dumps. loads converts JSON source text to a Python value, while dumps goes the other way.
After you fix that, based on the JSON snippet at the top of your question, readable_json will be a list, and so readable_json['firstName'] is meaningless. The correct way to get the 'firstName' field of every element of a list is to eliminate the playerstuff = readable_json['firstName'] line and change for i in playerstuff: to for i in readable_json:.
You can simplify your code down to
url = "http://worldcup.kimonolabs.com/api/players?apikey=xxx"
json_obj = urllib2.urlopen(url).read
player_json_list = json.loads(json_obj)
for player in readable_json_list:
print player['firstName']
You were trying to access a list element using dictionary syntax. the equivalent of
foo = [1, 2, 3, 4]
foo["1"]
It can be confusing when you have lists of dictionaries and keeping the nesting in order.