Python, Python dictionaries and JSON (JavaScript Object Notation - a lightweight data-interchange format) are really good combination. JSON allows storing, reading and transferring data in reliable and readable way for humans and machines.
In this post:
- Convert python dictionary to JSON
- Convert JSON to Python dict
- Read JSON from URL
- Read JSON string and write it to file
- Iterate/loop over json object
- Format JSON
- Errors
- AttributeError: 'str' object has no attribute 'loads'
- AttributeError: 'str' object has no attribute 'items'
- References
Convert Python dictionary to JSON
Working with JSON you will need to load module json. The method used for conversion from Python dictionary to JSON format is json.dumps()
:
import json
pdict = {'team': 'Brazil', 'position': 1, 'host': True, 'lastGame': 'Win'}
dictToJson = json.dumps(pdict)
print(type(dictToJson))
print(dictToJson)
result:
<class 'str'>
{"lastGame": "Win", "host": true, "position": 1, "team": "Brazil"}
As you can see the output is a JSON string.
Convert JSON to python dict
The reverse operation is very simple and use method json.loads()
. The usage is self-explaining:
import json
jsonString = '{"host": true, "lastGame": "Win", "team": "Brazil", "position": 1}'
jsonToDict = json.loads(jsonString)
print(type(jsonToDict))
print(jsonString)
result:
<class 'dict'>
{"host": true, "lastGame": "Win", "team": "Brazil", "position": 1}
The output is a Python dictionary(or a map).
Read JSON from URL
In many cases you will need to open a remote JSON resource by providing the URL address. this can be done by module JSON and urllib:
import json
import urllib.request
with urllib.request.urlopen("http://maps.googleapis.com/maps/api/geocode/json?address=london") as url:
data = json.loads(url.read().decode())
print(data)
result:
{'status': 'OK', 'results': [{'address_components': [{'short_name': 'London', 'long_name': 'London',
'types': ['locality', 'political']}, {'short_name': 'London', 'long_name': 'London', 'types': ['postal_town']}, {'short_name': 'Greater London', 'long_name': 'Greater London', 'types': ['administrative_area_level_2', 'political']},
{'short_name': 'England', 'long_name': 'England', 'types': ['administrative_area_level_1', 'political']},
{'short_name': 'GB', 'long_name': 'United Kingdom', 'types': ['country', 'political']}], 'types': ['locality', 'political'], 'geometry': {'bounds':
{'southwest': {'lat': 51.38494009999999, 'lng': -0.3514683}, 'northeast': {'lat': 51.6723432, 'lng': 0.148271}}, 'viewport': {'southwest': {'lat': 51.38494009999999, 'lng': -0.3514683}, 'northeast': {'lat': 51.6723432, 'lng': 0.148271}},
'location': {'lat': 51.5073509, 'lng': -0.1277583}, 'location_type': 'APPROXIMATE'}, 'place_id': 'ChIJdd4hrwug2EcRmSrV3Vo6llI', 'formatted_address': 'London, UK'}]}
Then you can work with your JSON data.
Read JSON string and write it to file
If we work with big data or large sets of data you may want to read and write the information to external file.
This can be done with method:
json.dump(jsonString, outfile)
import json
jsonString = {'team': 'Brazil', 'position': 1, 'host': True, 'lastGame': 'Win'}
with open('data.json', 'w') as outfile:
json.dump(jsonString, outfile)
result:
{"position": 1, "redcard": false, "team": "Brazil", "host": true}
If we provide an JSON string than you will get escape characters in the output:
import json
jsonString = '{"host": true, "lastGame": "Win", "team": "Brazil", "position": 1}'
with open('data.json', 'w') as outfile:
json.dump(jsonString, outfile)
result:
"{\"host\": true, \"lastGame\": \"Win\", \"team\": \"Brazil\", \"position\": 1}"}
The output file is in the same folder as the running script and as you can see there are escape slashes to the output.
Iterate/loop over json object
There are several ways for iterating a JSON object in python. The first one uses method items():
import json
for key, value in jsonObject.items():
print("The key and value are ({}) = ({})".format(key, value))
result:
key = value: (team) = (Brazil)
key = value: (lastGame) = (Win)
key = value: (host) = (True)
key = value: (position) = (1)
The other way is by accessing the JSON elements one by one:
import json
jsonObject = json.loads(jsonString)
for key in jsonObject:
value = jsonObject[key]
print("key = value: ({}) = ({})".format(key, value))
result:
key = value: (team) = (Brazil)
key = value: (lastGame) = (Win)
key = value: (host) = (True)
key = value: (position) = (1)
Prettyprint a JSON file with Python
Prettyprint a JSON file with Python
Method: json.dumps()
can be used for formatting and pretty printing of JSON files.
It is possible to customize it like setting indentation and sorting:
json.dumps(parsed, indent=4, sort_keys=True)
JSON Formatter and Validator
Toptal offers an interesting and useful tool for beginners: Toptal's JSON Formatter with Regex Search.
It can help with JSON:
- validation
- formatting
- convertion
- regex search
Once the JSON is converted and validated we can copy the result:
Errors for python and json
AttributeError: 'str' object has no attribute 'items'
If you provide a string instead of dictionary you will get this error. Example to reproduce the error:
jsonString = '{"host": true, "lastGame": "Win", "team": "Brazil", "position": 1}'.items()
and the correct one is:
jsonString = '{"host": true, "lastGame": "Win", "team": "Brazil", "position": 1}'
jsonObject = json.loads(jsonString).items()
AttributeError: 'str' object has no attribute 'loads'
The other common mistake when you are working with JSON and python(and not only) is giving a name to variable which is reserved name. For example variable named json. This will case the error:
json = '{"host": true, "lastGame": "Win", "team": "Brazil", "position": 1}'
jsonToDict = json.loads(jsonString)
result in:
jsonToDict = json.loads(jsonString)
AttributeError: 'str' object has no attribute 'loads'
References
- Introducing JSON
- Python 3 -json — JSON encoder and decoder
- Python 2 - urllib — Open arbitrary resources by URL
- Python 3 - urllib — URL handling modules