Python JSON encoding
Question:
I’m trying to encode data to JSON in Python and I been having a quite a bit of trouble. I believe the problem is simply a misunderstanding.
I’m relatively new to Python and never really got familiar with the various Python data types, so that’s most likely what’s messing me up.
Currently I am declaring a list, looping through and another list, and appending one list within another:
import simplejson, json
data = [['apple', 'cat'], ['banana', 'dog'], ['pear', 'fish']]
x = simplejson.loads(data)
# >>> typeError: expected string or buffer..
x = simplejson.dumps(stream)
# >>> [["apple", "cat"], ["banana", "dog"], ["pear", "fish"]]
# - shouldn't JSON encoded strings be like: {{"apple":{"cat"},{"banana":"dog"}}
So I either:
- I don’t understand JSON Syntax
- I don’t understand the Pythons JSON module(s)
- I’m using an inappropriate data type.
Answers:
The data you are encoding is a keyless array, so JSON encodes it with [] brackets. See www.json.org for more information about that. The curly braces are used for lists with key/value pairs.
From www.json.org:
JSON is built on two structures:
A collection of name/value pairs. In
various languages, this is realized as
an object, record, struct, dictionary,
hash table, keyed list, or associative
array. An ordered list of values. In
most languages, this is realized as an
array, vector, list, or sequence.
An object is an unordered set of
name/value pairs. An object begins
with { (left brace) and ends with }
(right brace). Each name is followed
by : (colon) and the name/value pairs
are separated by , (comma).
An array is an ordered collection of
values. An array begins with [ (left
bracket) and ends with ] (right
bracket). Values are separated by ,
(comma).
Python lists
translate to JSON arrays
. What it is giving you is a perfectly valid JSON string that could be used in a Javascript application. To get what you expected, you would need to use a dict
:
>>> json.dumps({'apple': 'cat', 'banana':'dog', 'pear':'fish'})
'{"pear": "fish", "apple": "cat", "banana": "dog"}'
In simplejson
(or the library json
in Python 2.6 and later), loads
takes a JSON string and returns a Python data structure, dumps
takes a Python data structure and returns a JSON string. JSON string can encode Javascript arrays, not just objects, and a Python list corresponds to a JSON string encoding an array. To get a JSON string such as
{"apple":"cat", "banana":"dog"}
the Python object you pass to json.dumps
could be:
dict(apple="cat", banana="dog")
though the JSON string is also valid Python syntax for the same dict
. I believe the specific string you say you expect is simply invalid JSON syntax, however.
JSON uses square brackets for lists ( [ "one", "two", "three" ]
) and curly brackets for key/value dictionaries (also called objects in JavaScript, {"one":1, "two":"b"}
).
The dump is quite correct, you get a list of three elements, each one is a list of two strings.
if you wanted a dictionary, maybe something like this:
x = simplejson.dumps(dict(data))
>>> {"pear": "fish", "apple": "cat", "banana": "dog"}
your expected string (‘{{"apple":{"cat"},{"banana":"dog"}}
‘) isn’t valid JSON. A
So, simplejson.loads takes a json string and returns a data structure, which is why you are getting that type error there.
simplejson.dumps(data) comes back with
'[["apple", "cat"], ["banana", "dog"], ["pear", "fish"]]'
Which is a json array, which is what you want, since you gave this a python array.
If you want to get an “object” type syntax you would instead do
>>> data2 = {'apple':'cat', 'banana':'dog', 'pear':'fish'}
>>> simplejson.dumps(data2)
'{"pear": "fish", "apple": "cat", "banana": "dog"}'
which is javascript will come out as an object.
Try:
import simplejson
data = {'apple': 'cat', 'banana':'dog', 'pear':'fish'}
data_json = "{'apple': 'cat', 'banana':'dog', 'pear':'fish'}"
simplejson.loads(data_json) # outputs data
simplejson.dumps(data) # outputs data_joon
NB: Based on Paolo’s answer.
I think you are simply exchanging dumps and loads.
>>> import json
>>> data = [['apple', 'cat'], ['banana', 'dog'], ['pear', 'fish']]
The first returns as a (JSON encoded) string its data argument:
>>> encoded_str = json.dumps( data )
>>> encoded_str
'[["apple", "cat"], ["banana", "dog"], ["pear", "fish"]]'
The second does the opposite, returning the data corresponding to its (JSON encoded) string argument:
>>> decoded_data = json.loads( encoded_str )
>>> decoded_data
[[u'apple', u'cat'], [u'banana', u'dog'], [u'pear', u'fish']]
>>> decoded_data == data
True
I’m trying to encode data to JSON in Python and I been having a quite a bit of trouble. I believe the problem is simply a misunderstanding.
I’m relatively new to Python and never really got familiar with the various Python data types, so that’s most likely what’s messing me up.
Currently I am declaring a list, looping through and another list, and appending one list within another:
import simplejson, json
data = [['apple', 'cat'], ['banana', 'dog'], ['pear', 'fish']]
x = simplejson.loads(data)
# >>> typeError: expected string or buffer..
x = simplejson.dumps(stream)
# >>> [["apple", "cat"], ["banana", "dog"], ["pear", "fish"]]
# - shouldn't JSON encoded strings be like: {{"apple":{"cat"},{"banana":"dog"}}
So I either:
- I don’t understand JSON Syntax
- I don’t understand the Pythons JSON module(s)
- I’m using an inappropriate data type.
The data you are encoding is a keyless array, so JSON encodes it with [] brackets. See www.json.org for more information about that. The curly braces are used for lists with key/value pairs.
From www.json.org:
JSON is built on two structures:
A collection of name/value pairs. In
various languages, this is realized as
an object, record, struct, dictionary,
hash table, keyed list, or associative
array. An ordered list of values. In
most languages, this is realized as an
array, vector, list, or sequence.An object is an unordered set of
name/value pairs. An object begins
with { (left brace) and ends with }
(right brace). Each name is followed
by : (colon) and the name/value pairs
are separated by , (comma).An array is an ordered collection of
values. An array begins with [ (left
bracket) and ends with ] (right
bracket). Values are separated by ,
(comma).
Python lists
translate to JSON arrays
. What it is giving you is a perfectly valid JSON string that could be used in a Javascript application. To get what you expected, you would need to use a dict
:
>>> json.dumps({'apple': 'cat', 'banana':'dog', 'pear':'fish'})
'{"pear": "fish", "apple": "cat", "banana": "dog"}'
In simplejson
(or the library json
in Python 2.6 and later), loads
takes a JSON string and returns a Python data structure, dumps
takes a Python data structure and returns a JSON string. JSON string can encode Javascript arrays, not just objects, and a Python list corresponds to a JSON string encoding an array. To get a JSON string such as
{"apple":"cat", "banana":"dog"}
the Python object you pass to json.dumps
could be:
dict(apple="cat", banana="dog")
though the JSON string is also valid Python syntax for the same dict
. I believe the specific string you say you expect is simply invalid JSON syntax, however.
JSON uses square brackets for lists ( [ "one", "two", "three" ]
) and curly brackets for key/value dictionaries (also called objects in JavaScript, {"one":1, "two":"b"}
).
The dump is quite correct, you get a list of three elements, each one is a list of two strings.
if you wanted a dictionary, maybe something like this:
x = simplejson.dumps(dict(data))
>>> {"pear": "fish", "apple": "cat", "banana": "dog"}
your expected string (‘{{"apple":{"cat"},{"banana":"dog"}}
‘) isn’t valid JSON. A
So, simplejson.loads takes a json string and returns a data structure, which is why you are getting that type error there.
simplejson.dumps(data) comes back with
'[["apple", "cat"], ["banana", "dog"], ["pear", "fish"]]'
Which is a json array, which is what you want, since you gave this a python array.
If you want to get an “object” type syntax you would instead do
>>> data2 = {'apple':'cat', 'banana':'dog', 'pear':'fish'}
>>> simplejson.dumps(data2)
'{"pear": "fish", "apple": "cat", "banana": "dog"}'
which is javascript will come out as an object.
Try:
import simplejson
data = {'apple': 'cat', 'banana':'dog', 'pear':'fish'}
data_json = "{'apple': 'cat', 'banana':'dog', 'pear':'fish'}"
simplejson.loads(data_json) # outputs data
simplejson.dumps(data) # outputs data_joon
NB: Based on Paolo’s answer.
I think you are simply exchanging dumps and loads.
>>> import json
>>> data = [['apple', 'cat'], ['banana', 'dog'], ['pear', 'fish']]
The first returns as a (JSON encoded) string its data argument:
>>> encoded_str = json.dumps( data )
>>> encoded_str
'[["apple", "cat"], ["banana", "dog"], ["pear", "fish"]]'
The second does the opposite, returning the data corresponding to its (JSON encoded) string argument:
>>> decoded_data = json.loads( encoded_str )
>>> decoded_data
[[u'apple', u'cat'], [u'banana', u'dog'], [u'pear', u'fish']]
>>> decoded_data == data
True