I am trying to read a JSON file and iterate through it, for instance I am trying to print the children, or the firstname, or the hobbies etc...
The JSON file looks like this:
{
"firstName": "Jane",
"lastName": "Doe",
"hobbies": ["running", "sky diving", "singing"],
"age": 35,
"children": [
{
"firstName": "Alice",
"age": 6
},
{
"firstName": "Bob",
"age": 8
}
]
},
{
"firstName": "Mike",
"lastName": "Smith",
"hobbies": ["bowling", "photography", "biking"],
"age":40,
"children": [
{
"firstName": "Steve",
"age": 10
},
{
"firstName": "Sara",
"age": 18
}
]
}
I'm loading the json file using the following code:
import json
with open('test.json') as f:
data = json.load(f)
and I can print parts of the first record fine like this:
print(data['children'])
print(data['hobbies'])
[{'firstName': 'Alice', 'age': 6}, {'firstName': 'Bob', 'age': 8}]
['running', 'sky diving', 'singing']
I'd like to iterate through the records though so I can print pieces of the 2nd entry as well (or 3rd, or 20th if applicable)
When I try this however:
for key, value in data.items():
print(key, value)
It still just returns the first entry:
firstName Jane
lastName Doe
hobbies ['running', 'sky diving', 'singing']
age 35
children [{'firstName': 'Alice', 'age': 6}, {'firstName': 'Bob', 'age': 8}]
Any ideas?
The Problem you are facing is you are having the data as a single json.
You need to make it as an array. Something like this.
[{ // notice additional [
"firstName": "Jane",
"lastName": "Doe",
"hobbies": ["running", "sky diving", "singing"],
"age": 35,
"children": [
{
"firstName": "Alice",
"age": 6
},
{
"firstName": "Bob",
"age": 8
}
]
},
{
"firstName": "Mike",
"lastName": "Smith",
"hobbies": ["bowling", "photography", "biking"],
"age":40,
"children": [
{
"firstName": "Steve",
"age": 10
},
{
"firstName": "Sara",
"age": 18
}
]
}] // notice additional ]
Then you need to loop it over the list and then as per what you have written. Something like this
import json
with open('abc.json') as f:
data = json.load(f)
for element in data:
for key, value in element.items():
print(key, value)
To covert your file be more std JSON, and open it add [ and ], to make it as json list. and whole code paste below:
import json
f = open("test_json.txt", "r")
contents = f.readlines()
f.close()
contents.insert(0, "[")
f = open("test_json.txt", "w")
contents = "".join(contents)
f.write(contents)
f.write("]")
f.close()
with open("test_json.txt", "r") as fd:
d = json.load(fd)
for i in d:
print(i)
Related
for an input json
[{
"Name": "John",
"Age": "23",
"Des": "SE"
},
{
"Name": "Rai",
"Age": "33",
"Des": "SSE"
},
{
"Name": "James",
"Age": "42",
"Des": "SE"
}
]
I want to filter out the json data where only "Des":"SE" is true
required output
[{
"Name": "John",
"Age": "23"
},
{
"Name": "James",
"Age": "42"
}
]
A list comprehension should do it:
out = [{'Name':d['Name'], 'Age':d['Age']} for d in lst if d['Des']=='SE']
Another way:
out = [d for d in lst if d.pop('Des')=='SE']
Output:
[{'Name': 'John', 'Age': '23'}, {'Name': 'James', 'Age': '42'}]
To make it more dynamic if each json has more elements:
import json
input_str = '[{"Name": "John", "Age": "23", "Des": "SE"}, {"Name": "Rai", "Age": "33", "Des": "SSE"}, {"Name": "James", "Age": "42", "Des": "SE"}]'
input_list = json.loads(input_str)
# If you already converted to a list of dicts, then you don't need the above
# Using pop here removes the key you are using to filter
output = [each for each in input_list if each.pop("Des") == "SE"]
using the json module, you can load a file using loads or a string using load. From there, it acts as a normal python list of dictionaries which you can iterate over and check the keys of. From there, you simply create a new list of dictionaries that match your desired pattern and remove the key you are no longer using. Example:
import json
jsonString = """[{
"Name": "John",
"Age": "23",
"Des": "SE"
},
{
"Name": "Rai",
"Age": "33",
"Des": "SSE"
},
{
"Name": "James",
"Age": "42",
"Des": "SE"
}
]"""
jsonList = json.loads(jsonString)
filteredList = []
def CheckDes(dataDict: dict):
if dataDict['Des'] == 'SE':
dataDict.pop('Des')
filteredList.append(dataDict)
print(jsonList)
"""
[
{
'Name': 'John',
'Age': '23',
'Des': 'SE'
},
{
'Name': 'Rai',
'Age': '33',
'Des': 'SSE'
},
{
'Name': 'James',
'Age': '42',
'Des': 'SE'
}
]"""
[CheckDes(dataDict) for dataDict in jsonList]
print(filteredList)
"""[
{
'Name': 'John',
'Age': '23'
},
{
'Name': 'James',
'Age': '42'
}
]
"""
{
'data':[
"firstName": "Jane",
"lastName": "Doe",
"hobbies": ["running", "sky diving", "singing"],
"age": 35,
"children": [
{
"firstName": "Sandy,
"age": 6
"values":[
{
'value' :908
}
]
},
{
"firstName": "Alice",
"age": 7
"values":[
{
'value' :0123
}
]
}
{
"firstName": "Dany",
"age": 8
"values":[
{
'value' :0193
}
]
}
]
}
**This is my json file .I try to reach first names ,values and age each block and write database.**I tried a lot of things and I cant run ..
.
.
results=r.json()
for k in results['data']:
for k1 in k['children']:
data={"firstname":k1['firstName']....?Values?)
How can I reach each block values and every values in one json format ?
I believe your example is coming from the web. But as Alberto Poljak and fizzybear pointed your json format was somewhat broken.
I corrected it here and there and in this format it should work:
{
"data":
{
"firstName": "Jane",
"lastName": "Doe",
"hobbies": ["running", "sky diving", "singing"],
"age": 35,
"children": [
{
"firstName": "Sandy",
"age": 6,
"values":[
{
"value" :908
}
]
},
{
"firstName": "Alice",
"age": 7,
"values":[
{
"value" :123
}
]
},
{
"firstName": "Dany",
"age": 8,
"values":[
{
"value" :193
}
]
}
]
}
}
If you save the above in a file "family.json" then this sample code should be working fine:
import json
with open('family.json') as json_file:
data = json.load(json_file)
p = data['data']['children']
for r in p:
print('First name: %s' % r['firstName'])
print('Age: %d' % r['age'])
print('')
For quick review of json files you can use e.g. https://codebeautify.org/jsonviewer, where you can validate it or see its content in a tree structure etc..
There is a big jsonfile I am trying to manipulate using jmespath. In order to do so I need to generate a full path list to use as reference because not all the items will be needed.
Here is a sample json:
data = {
"firstName": "Jane",
"lastName": "Doe",
"hobbies": ["running", "sky diving", "singing"],
"age": 35,
"children": [
{
"firstName": "Alice",
"age": 6,
"hobbies": ["swimming", "painting"]
},
{
"firstName": "Bob",
"age": 8,
"hobbies": ["video games", "soccer"]
}
]
}
I need to script to generate:
firstName.Jane
lastName.Doe
hobbies.running
hobbies.sky diving
hobbies.singing
age.35
children[0].firstname.Alice
children[0].age.6
children[0].hobbies.swimming
children[0].hobbies.painting
children[1].firstname.Bob
children[1].age.8
children[1].hobbies.video games
children[1].hobbies.soccer
The JSON might be up to 3-4 levels in depth. Been trying several options but can't wrap my head around how to achieve this...
This should work for any depth of JSON (not taking in account recursion limit):
data = {
"firstName": "Jane",
"lastName": "Doe",
"hobbies": ["running", "sky diving", "singing"],
"age": 35,
"children": [
{
"firstName": "Alice",
"age": 6,
"hobbies": ["swimming", "painting"]
},
{
"firstName": "Bob",
"age": 8,
"hobbies": ["video games", "soccer"]
}
]
}
def traverese(d, current_key=''):
if isinstance(d, dict):
for k, v in d.items():
yield from traverese(v, current_key + k + '.')
elif isinstance(d, list):
for i, vv in enumerate(d):
yield from traverese(vv, current_key + '[' + str(i) + '].')
else:
yield current_key + str(d)
for index in traverese(data):
print(index)
Prints:
firstName.Jane
lastName.Doe
hobbies.[0].running
hobbies.[1].sky diving
hobbies.[2].singing
age.35
children.[0].firstName.Alice
children.[0].age.6
children.[0].hobbies.[0].swimming
children.[0].hobbies.[1].painting
children.[1].firstName.Bob
children.[1].age.8
children.[1].hobbies.[0].video games
children.[1].hobbies.[1].soccer
You can use recursive code.
This is just a reference of code, and you can use this reference to recursively check with json
for keys in data:
#Here we are checking if type is list or dict
if type(data[keys]) in [list,dict]:
for x in data[keys]:
print(x)
I am writing a json file from information extracted from a url. How do I print each element of the dictionary on a separate line?
This is my current code:
dct=[{"name": name,
"cuisine": cuisine,
"price-range": price,
"address": address,
"rating": rating,
"reviews": score,
"district": district,
"url": link
}]
with open('openrice_data.json', 'a') as file:
file.write(json.dumps(dct))
For example, it currently prints like this:
[{"cuisine": ["Japanese", "Hot Pot", "Buffet"], "rating": [3.5], "address": [22.3825, 114.1901], "url": ["https://www.openrice.com/en/hongkong/r-wagyu-more-sha-tin-japanese-hot-pot-r172321"], "reviews": [35, 17, 8], "name": "Wagyu More", "price-range": ["$101-200"], "district": ["Sha Tin"]}]
I would like it to print like this:
[
{"name": "Chan Kun Kee",
"cuisine": ["Guang Dong", "Dai Pai Dong"],
"price-range": "$51-100",
"address": [22.3884, 114.1958],
"rating": 3.5,
"reviews": [216, 95, 38],
"district": "Shatin",
"url": "www.openrice.com/en/hongkong/r-chan-kun-kee-sha-tin-guangdong-r7918"
}
]
Update Actually what you have is a list of dictionaries. When you want to add more elements you need to remove the [] around the dictionary.
To slve your specific problem you want to use indent=0. Also consider using json.dump directly.
import json
l=[]
dct={"name": 'name',
"cuisine": 'cuisine',
"price-range": 'price',
"address": 'address',
"rating": 'rating',
"reviews": 'score',
"district": 'district',
"url": 'link'
}
l.append(dct)
with open('openrice_data.json', 'w') as file:
json.dump(l,file,indent=0)
Output:
[
{
"name": "name",
"cuisine": "cuisine",
"price-range": "price",
"address": "address",
"rating": "rating",
"reviews": "score",
"district": "district",
"url": "link"
}
]
Continuing
To add more elements you need to do this:
# Load json to list
with open('openrice_data.json') as f:
l = json.load(f)
# A new dict
dct2={"name": 'name',
"cuisine": 'cuisine',
"price-range": 'price',
"address": 'address',
"rating": 'rating',
"reviews": 'score',
"district": 'district',
"url": 'link'
}
# Append new dict
l.append(dct2)
with open('openrice_data.json', 'w') as file:
json.dump(l,file,indent=0)
Output now contains a list with 2 dicts.
[
{
"name": "name",
"cuisine": "cuisine",
"price-range": "price",
"address": "address",
"rating": "rating",
"reviews": "score",
"district": "district",
"url": "link"
},
{
"name": "name",
"cuisine": "cuisine",
"price-range": "price",
"address": "address",
"rating": "rating",
"reviews": "score",
"district": "district",
"url": "link"
}
]
Don't use json, pprint is perfect for this job.
from pprint import pprint
obj = [{"cuisine": ["Japanese", "Hot Pot", "Buffet"], "rating": [3.5], "address": [22.3825, 114.1901], "url": ["https://www.openrice.com/en/hongkong/r-wagyu-more-sha-tin-japanese-hot-pot-r172321"], "reviews": [35, 17, 8], "name": "Wagyu More", "price-range": ["$101-200"], "district": ["Sha Tin"]}]
with open('dumpfile.json', 'w+') as f:
pprint(obj, f)
There are a few parameters for customization, please check the doc for more details :
https://docs.python.org/3/library/pprint.html
Use prettyprinter:
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(dct)
Also: you are currently putting the dict in a list. [] is a list {} is a dict in python.
By putting [{}] you are putting the dict into a list. Just remove the [].
Other people have remarked on using pprint, but I would like to add that pprint prints the representation of the Python values in your dictionary. They are not always the same as their JSON counterparts, for example:
>>> from pprint import pprint
>>> d1 = {"value": None}
>>> pprint(d1)
{'value': None}
(the correct JSON serialization here is {"value": null}
The better option, for these kinds of values, is to use json.dump or json.dumps. You can use the indent parameter to sort of make it print one line per element. Note though that this will also print each list element into their separate lines (so you don't exactly get one line per one JSON key):
>>> d2 = [
... {"name": "Chan Kun Kee",
... "cuisine": ["Guang Dong", "Dai Pai Dong"],
... "price-range": "$51-100",
... "address": [22.3884, 114.1958],
... "rating": 3.5,
... "reviews": [216, 95, 38],
... "district": "Shatin",
... "url": "www.openrice.com/en/hongkong/r-chan-kun-kee-sha-tin-guangdong-r7918"
... }
... ]
>>> print(json.dumps(d2, indent=2))
[
{
"name": "Chan Kun Kee",
"cuisine": [
"Guang Dong",
"Dai Pai Dong"
],
"price-range": "$51-100",
"address": [
22.3884,
114.1958
],
"rating": 3.5,
"reviews": [
216,
95,
38
],
"district": "Shatin",
"url": "www.openrice.com/en/hongkong/r-chan-kun-kee-sha-tin-guangdong-r7918"
}
]
But you're guaranteed to at least always get the correct JSON. Plus, you can also extend the behavior with your own JSON encoder. This allows you, for example, to serialize Python datetime objects into JSON strings.
I have json file i what to read all the values
data=""" {"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}
{
"maps":[
{"id":"apple","iscategorical":"0"},
{"id":"ball","iscategorical":"0"}
],
"mask":{"id1":"aaaaa"},
"mask":{"id1":"bbb"},
"mask":{"id1":"cccccc"},
"om_points":"value",
"parameters":
{"id":"valore"}
}"""
out = json.loads(data)
how to get all values
firstname
lastname
mask.id1
map.id
output:
[(firstname_vaues,lastname_values,mask.id1,map.id)
(firstname_vaues,lastname_values,mask.id1,map.id) ......]
please help me
First thing, there are two json objects in your data string. So you cannot use json.loads(data). You can seperate them by a charcter like ";" . Then split the string and use json.loads on each of them.Use following code.
import json
data=""" {
"employees": [{
"firstName": "John",
"lastName": "Doe"
}, {
"firstName": "Anna",
"lastName": "Smith"
}, {
"firstName": "Peter",
"lastName": "Jones"
}]
};{
"maps": [{
"id": "apple",
"iscategorical": "0"
}, {
"id": "ball",
"iscategorical": "0"
}],
"mask": {
"id1": "aaaaa"
},
"mask": {
"id1": "bbb"
},
"mask": {
"id1": "cccccc"
},
"om_points": "value",
"parameters": {
"id": "valore"
}
}"""
splitdata = data.split(';')
datatop = json.loads(splitdata[0])
databottom = json.loads(splitdata[1])
Then you can access required fields as follows
print(datatop['employees'][0]['firstName'])
print(datatop['employees'][0]['lastName'])
print(databottom['mask']['id1'])
print(databottom['maps'][0]['id'])