How do I read an JSON object in python? - python

Im currently working on a Python Pygame project were I have to work with JSON files. Im trying to read of an JSON file but I just cant get it to print what I want to know.
Here is the JSON file
"pokemons": {
"5": {
"name": "Snivy",
"type": "Grass",
"hp": 45,
"attack": 45,
"defence": 55,
"speed": 63,
"moves": [
"Tackle",
"Leer",
"null",
"null"
],
"level": 4,
"xp": 54
},
"2": {
"name": "Tepig",
"type": "Fire",
"hp": 65,
"attack": 63,
"defence": 45,
"speed": 45,
"moves": [
"Tackle",
"Tail Whip",
"Ember",
"null"
],
"level": 7,
"xp": 11
}
}
}
Im trying to read the "name", "type", ect from the different "ID's" aka "5" and "2", but I can only make it print "5" and "2" from the "pokemons" array
with open("data.json", "r") as f:
data = json.load(f)
for i in data["pokemons"]:
print(i)

You've titled this json read from array inside of array python, but you don't have JSON arrays (translated into Python lists) here - you have JSON objects (translated into Python dicts).
for i in data["pokemons"]:
data["pokemons"] is a dict, so iterating over it like this gives you the keys - "5" and "2"`. You can use those to index into the data:
data["pokemons"][i]
That gives you one of the objects (dicts) representing an individual pokemon, from which you can access the name:
data["pokemons"][i]["name"]
Better yet, you can loop over the values of data["pokemons"] directly, instead of the keys:
for pokemon in data["pokemons"].values():
name = pokemon["name"]
Or you can get both at once using .items(), for example:
for pid, pokemon in data["pokemons"].items():
# use string formatting to display the pid and matching name together.
print(f"pokemon number {pid} has name {pokemon['name']}")

My Solution
data = '{"pokemons": {"5": {"name": "Snivy","type": "Grass","hp": 45,"attack": 45,"defence": 55,"speed": 63,"moves": ["Tackle","Leer","null","null"],"level": 4,"xp": 54},"2": {"name": "Tepig","type": "Fire","hp": 65,"attack": 63,"defence": 45,"speed": 45,"moves": ["Tackle","Tail Whip","Ember","null"],"level": 7,"xp": 11}}}}'
datadict = json.loads(data)
dataOfId = datadict['pokemons']
for i in dataOfId:
print(dataOfId[i]["name"])
print(dataOfId[i]["type"])

Related

Parse the inside json data of all variables

Im working on big json data . In every data set ther will be Name,Type,Value. Im actually need to parse the all type which as equal to "Shirt". I don't know to parse the inside json data.
x={
"Data": "Ecommerce",
"Host":{
"Items": [
[
{
"Name": "cot",
"Value": 99,
"Type": "Shirt"
},
{
"Name": "ploy",
"Value": 90,
"Type": "Pant"
},
{
"Name": "lyc",
"Value": 22,
"Type":"Shirt"
}
]
],
}}
k=x.get("Host")
print(k)
The above code will Display all data inside the Host.
What I'm trying to get output as parse only the Type: Shirt and Value of the Shirt .
I tried with some Def ,loop concepts but i can't able to achieve my output.
Output I'm looking for :-
If Type = Shirt , need parse that json data
Cot:90
Lyc:22
In dict format
This shows how to access the data. I assume you can change this to create a dictionary.
for item in x['Host']['Items'][0]:
if item['Type'] == 'Shirt':
print(item['Name'],':',item['Value'])
This is an example to do it with short for
items = x["Host"]["Items"]
shirt_values = {item["Name"]: item["Value"] for sublist in items for item in sublist if item["Type"] == "Shirt"}

Extract data from json, append using for loop and save as CSV

I have extracted id, username, and name for 100 followers for 102 politicians using Tweepy. The data is stored in a JSON file named pol_followers. Now I wish to append id and username and save it as a CSV file using the function below. However, when using the function in the last line append_followers_to_csv(pol_followers, "pol_followers.csv") I get the error seen at the bottom.
# Structure of pol_followers. The full pol_followers is much longer...
print(json.dumps(pol_followers, indent=4, sort_keys=True)) # see json data structure
[
{
"data": [
{
"id": "1464206217807601666",
"name": "terry alex",
"username": "terryal51850644"
},
{
"id": "1479032154394968064",
"name": "Charles Williams",
"username": "Charles99924770"
},
{
"id": "2526015770",
"name": "LISA P",
"username": "LISAP0910"
},
{
"id": "2957692520",
"name": "fayaz ahmad",
"username": "ahmadfayaz202"
}
],
"meta": {
"next_token": "F6HS7IU5SRGHEZZZ",
"result_count": 100
}
},
{
"data": [
{
"id": "2482703136",
"name": "HieuVu",
"username": "sachieuhaihanh"
},
{
"id": "580882148",
"name": "Maxine D. Harmon",
"username": "maxxximd"
},
{
"id": "1478867472841334787",
"name": "RBPsych1",
"username": "RBPsych1"
# Create file
csv_follower_file = open("pol_followers.csv", "a", newline="", encoding='utf-8')
csv_follower_writer = csv.writer(csv_follower_file)
# Create headers for the data I want to save. I only want to save these columns in my dataset
csv_follower_writer.writerow(
['id', 'username'])
csv_follower_file.close()\
def append_followers_to_csv(pol_followers, csv_follower_file):
# A counter variable
global follower_id, username
counter = 0
# Open OR create the target CSV file
csv_follower_file = open(csv_follower_file, "a", newline="", encoding='utf-8')
csv_follower_writer = csv.writer(csv_follower_file)
for ids in pol_followers['data']:
# 1. follower ID
follower_id = ids['id']
# 2. follower username
username = ids['username']
# Assemble all data in a list
ress = [follower_id, username]
# Append the result to the CSV file
csv_follower_writer.writerow(ress)
counter += 1
# When done, close the CSV file
csvFile.close()
# Print the number of tweets for this iteration
print("# of Tweets added from this response: ", counter)
append_followers_to_csv(pol_followers, "pol_followers.csv") # Save tweet data in a csv file
File "<input>", line 1, in <module>
File "<input>", line 11, in append_followers_to_csv
TypeError: list indices must be integers or slices, not str
You are just missing additional loop, like so:
for each_dict in pol_followers:
for ids in each_dict['data']:
follower_id = ids['id']
username = ids['username']
You seem to have wrapped your JSON object in a list, so instead of getting the 'data' bit of the JSON, you are getting the 'data'th element of a list when you are iterating in your append_followers_to_csv function, which you can't do in python. Try removing the square brackets around the JSON or making it for ids in pol_followers[0]['data'].

Reading and parsing JSON with ijson [duplicate]

I have the following data in my JSON file:
{
"first": {
"name": "James",
"age": 30
},
"second": {
"name": "Max",
"age": 30
},
"third": {
"name": "Norah",
"age": 30
},
"fourth": {
"name": "Sam",
"age": 30
}
}
I want to print the top-level key and object as follows:
import json
import ijson
fname = "data.json"
with open(fname) as f:
raw_data = f.read()
data = json.loads(raw_data)
for k in data.keys():
print k, data[k]
OUTPUT:
second {u'age': 30, u'name': u'Max'}
fourth {u'age': 30, u'name': u'Sam'}
third {u'age': 30, u'name': u'Norah'}
first {u'age': 30, u'name': u'James'}
So, far so good. However if I want to this same thing for a huge file, I would have to read it all in-memory. This very slow and requires lots of memory.
I want use an incremental JSON parser ( ijson in this case ) to achieve what I described earlier:
The above code was taken from: No access to top level elements with ijson?
with open(fname) as f:
json_obj = ijson.items(f,'').next() # '' loads everything as only one object.
for (key, value) in json_obj.items():
print key + " -> " + str(value)
This is not suitable either, because it also reads the whole file in memory. This not truly incremental.
How can I do incremental parsing of top-level keys and corresponding objects, of a JSON file in Python?
Since essentially json files are text files, consider stripping the top level as string. Basically, use a read file iterable approach where you concatenate a string with each line and then break out of the loop once the string contains the double braces }} signaling the end of the top level. Of course the double brace condition must strip out spaces and line breaks.
toplevelstring = ''
with open('data.json') as f:
for line in f:
if not '}}' in toplevelstring.replace('\n', '').replace('\s+',''):
toplevelstring = toplevelstring + line
else:
break
data = json.loads(toplevelstring)
Now if your larger json is wrapped in square brackets or other braces, still run above routine but add the below line to slice out first character, [, and last two characters for comma and line break after top level's final brace:
[{
"first": {
"name": "James",
"age": 30
},
"second": {
"name": "Max",
"age": 30
},
"third": {
"name": "Norah",
"age": 30
},
"fourth": {
"name": "Sam",
"age": 30
}
},
{
"data1": {
"id": "AAA",
"type": 55
},
"data2": {
"id": "BBB",
"type": 1601
},
"data3": {
"id": "CCC",
"type": 817
}
}]
...
toplevelstring = toplevelstring[1:-2]
data = json.loads(toplevelstring)
Since version 2.6 ijson comes with a kvitems function that achieves exactly this.
Answer from github issue [file name changed]
import ijson
from ijson.common import ObjectBuilder
def objects(file):
key = '-'
for prefix, event, value in ijson.parse(file):
if prefix == '' and event == 'map_key': # found new object at the root
key = value # mark the key value
builder = ObjectBuilder()
elif prefix.startswith(key): # while at this key, build the object
builder.event(event, value)
if event == 'end_map': # found the end of an object at the current key, yield
yield key, builder.value
for key, value in objects(open('data.json', 'rb')):
print(key, value)

I cant append to my JSON array with Python

This doesn't seem to work with this line being the issue
data["Objects"]["Text"].append({"f":"var6", "g":"var7", "h":"var8"})
This is the entire function
def CreateTextJSON(TextObject):
print("s")
with open('base.json') as f:
data = json.load(f)
data["Objects"]["Text"].append({"f":"var6", "g":"var7", "h":"var8"})
with open('base.json', 'w') as f:
json.dump(data, f)
This is my JSON (base.json)
{
"Objects": [
{
"Type": "Menu",
"Path": "assets/images/mainmenu/mainmenu.png",
"Name": "MainMenu",
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Buttons": [],
"Text": []
}]
}
Im trying to add to the [Text] array but I can't seem to.
Credit to #Grismar "Also, the problem would seem to be that "Objects" is not a dictionary, but a list with 1 element, which is the dictionary, so you need data["Objects"][0]["Text"].append( ..."

Index JSON searches python

I have the next JSON that I get from a URL:
[{
"id": 1,
"version": 23,
"external_id": "2312",
"url": "https://example.com/432",
"type": "typeA",
"date": "2",
"notes": "notes",
"title": "title",
"abstract": "dsadasdas",
"details": "something",
"accuracy": 0,
"reliability": 0,
"severity": 12,
"thing": "32132",
"other": [
"aaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbb",
"cccccccccccccccc",
"dddddddddddddd",
"eeeeeeeeee"
],
"nana": 8
},
{
"id": 2,
"version": 23,
"external_id": "2312",
"url": "https://example.com/432",
"type": "typeA",
"date": "2",
"notes": "notes",
"title": "title",
"abstract": "dsadasdas",
"details": "something",
"accuracy": 0,
"reliability": 0,
"severity": 12,
"thing": "32132",
"other": [
"aaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbb",
"cccccccccccccccc",
"dddddddddddddd",
"eeeeeeeeee"
],
"nana": 8
}]
My code:
import json
import urllib2
data = json.load(urllib2.urlopen('http://someurl/path/to/json'))
print data
I want to know how to access to the part "abstract" of the object that has "id" equal to 2 for example. The part "id" is unique so I can use id to index my searchs.
Thanks!
Here's one way to do it. You can create a generator via a generator expression, call next to iterate that generator once, and get back the desired object.
item = next((item for item in data if item['id'] == 2), None)
if item:
print item['abstract']
See also Python: get a dict from a list based on something inside the dict
EDIT : If you'd like access to all elements of the list that have a given key value (for example, id == 2) you can do one of two things. You can either create a list via comprehension (as shown in the other answer), or you can alter my solution:
my_gen = (item for item in data if item['id'] == 2)
for item in my_gen:
print item
In the loop, item will iterate over those items in your list which satisfy the given condition (here, id == 2).
You can use list comprehention to filter:
import json
j = """[{"id":1,"version":23,"external_id":"2312","url":"https://example.com/432","type":"typeA","date":"2","notes":"notes","title":"title","abstract":"dsadasdas","details":"something","accuracy":0,"reliability":0,"severity":12,"thing":"32132","other":["aaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbb","cccccccccccccccc","dddddddddddddd","eeeeeeeeee"],"nana":8},{"id":2,"version":23,"external_id":"2312","url":"https://example.com/432","type":"typeA","date":"2","notes":"notes","title":"title","abstract":"dsadasdas","details":"something","accuracy":0,"reliability":0,"severity":12,"thing":"32132","other":["aaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbb","cccccccccccccccc","dddddddddddddd","eeeeeeeeee"],"nana":8}]"""
dicto = json.loads(j)
results = [x for x in dicto if "id" in x and x["id"]==2]
And then you can print the 'abstract' values like so:
for result in results:
if "abstract" in result:
print result["abstract"]
import urllib2
import json
data = json.load(urllib2.urlopen('http://someurl/path/to/json'))
your_id = raw_input('enter the id')
for each in data:
if each['id'] == your_id:
print each['abstract']
In the above code data is list and each is a dict you can easily access the dict object.

Categories