88
votes

I am trying to create a python dictionary which is to be used as a java script var inside a html file for visualization purposes. As a requisite, I am in need of creating the dictionary with all names inside double quotes instead of default single quotes which Python uses. Is there an easy and elegant way to achieve this.

    couples = [
               ['jack', 'ilena'], 
               ['arun', 'maya'], 
               ['hari', 'aradhana'], 
               ['bill', 'samantha']]
    pairs = dict(couples)
    print pairs

Generated Output:

{'arun': 'maya', 'bill': 'samantha', 'jack': 'ilena', 'hari': 'aradhana'}

Expected Output:

{"arun": "maya", "bill": "samantha", "jack": "ilena", "hari": "aradhana"}

I know, json.dumps(pairs) does the job, but the dictionary as a whole is converted into a string which isn't what I am expecting.

P.S.: Is there an alternate way to do this with using json, since I am dealing with nested dictionaries.

7
When you ask to print a dictionary, you're printing the conversion of the dictionary to a string anyway, so JSON is completely appropriate -- particularly if you're trying to interchange with Javascript. - Russell Borogove
You're not altering anything about the dictionary. You're creating a string representation of it. The dictionary doesn't contain single quotes. It contains strings. You are confused about what a dictionary is. - Russell Borogove
@RussellBorogove: Or, more fundamentally, confused about the difference between an actual string object and its representation. - abarnert
@ArunprasathShankar You need to explain why you think making double quotes the default is your only option. Converting to JSON doesn't preclude more updates. You can always convert to JSON again if there are more updates, right? - Jon-Eric
The question seems fundamentally misguided. The "print" keyword calls __str__ on the dictionary and converts is to a string just like json.dumps(pairs) does. The OP shows a basic misunderstanding he/she saids "but the dictionary as a whole is converted into a string which isn't what I am expecting." In fact, when you print an object, regardless of how you print it, the object is first converted to a string. - Raymond Hettinger

7 Answers

64
votes

You can construct your own version of a dict with special printing using json.dumps():

>>> import json
>>> class mydict(dict):
        def __str__(self):
            return json.dumps(self)

>>> couples = [['jack', 'ilena'], 
               ['arun', 'maya'], 
               ['hari', 'aradhana'], 
               ['bill', 'samantha']]    

>>> pairs =  mydict(couples) 
>>> print pairs
{"arun": "maya", "bill": "samantha", "jack": "ilena", "hari": "aradhana"}

You can also iterate:

>>> for el in pairs:
       print el

arun
bill
jack
hari
70
votes

json.dumps() is what you want here, if you use print json.dumps(pairs) you will get your expected output:

>>> pairs = {'arun': 'maya', 'bill': 'samantha', 'jack': 'ilena', 'hari': 'aradhana'}
>>> print pairs
{'arun': 'maya', 'bill': 'samantha', 'jack': 'ilena', 'hari': 'aradhana'}
>>> import json
>>> print json.dumps(pairs)
{"arun": "maya", "bill": "samantha", "jack": "ilena", "hari": "aradhana"}
8
votes
# do not use this until you understand it
import json

class doubleQuoteDict(dict):
    def __str__(self):
        return json.dumps(self)

    def __repr__(self):
        return json.dumps(self)

couples = [
           ['jack', 'ilena'], 
           ['arun', 'maya'], 
           ['hari', 'aradhana'], 
           ['bill', 'samantha']]
pairs = doubleQuoteDict(couples)
print pairs

Yields:

{"arun": "maya", "bill": "samantha", "jack": "ilena", "hari": "aradhana"}
7
votes

Here's a basic print version:

>>> print '{%s}' % ', '.join(['"%s": "%s"' % (k, v) for k, v in pairs.items()])
{"arun": "maya", "bill": "samantha", "jack": "ilena", "hari": "aradhana"}
4
votes

The premise of the question is wrong:

I know, json.dumps(pairs) does the job, but the dictionary 
as a whole is converted into a string which isn't what I am expecting.

You should be expecting a conversion to a string. All "print" does is convert an object to a string and send it to standard output.

When Python sees:

print somedict

What it really does is:

sys.stdout.write(somedict.__str__())
sys.stdout.write('\n')

As you can see, the dict is always converted to a string (afterall a string is the only datatype you can send to a file such as stdout).

Controlling the conversion to a string can be done either by defining __str__ for an object (as the other respondents have done) or by calling a pretty printing function such as json.dumps(). Although both ways have the same effect of creating a string to be printed, the latter technique has many advantages (you don't have to create a new object, it recursively applies to nested data, it is standard, it is written in C for speed, and it is already well tested).

The postscript still misses the point:

P.S.: Is there an alternate way to do this with using json, since I am
dealing with nested dictionaries.

Why work so hard to avoid the json module? Pretty much any solution to the problem of printing nested dictionaries with double quotes will re-invent what json.dumps() already does.

1
votes

The problem that has gotten me multiple times is when loading a json file.

import json
with open('json_test.json', 'r') as f:
    data = json.load(f)
    print(type(data), data)
    json_string = json.dumps(data)
    print(json_string)

I accidentally pass data to some function that wants a json string and I get the error that single quote is not valid json. I recheck the input json file and see the double quotes and then scratch my head for a minute.

The problem is that data is a dict not a string, but when Python converts it for you it is NOT valid json.

<class 'dict'> {'bill': 'samantha', 'jack': 'ilena', 'hari': 'aradhana', 'arun': 'maya'}
{"bill": "samantha", "jack": "ilena", "hari": "aradhana", "arun": "maya"}

If the json is valid and the dict does not need processing before conversion to string, just load as string does the trick.

with open('json_test.json', 'r') as f:
    json_string = f.read()
    print(json_string)
1
votes

It's Easy just 2 steps

step1:converting your dict to list

step2:iterate your list and convert as json .

For better understanding check down below snippet

import json
couples = [
               ['jack', 'ilena'], 
               ['arun', 'maya'], 
               ['hari', 'aradhana'], 
               ['bill', 'samantha']]
pairs = [dict(couples)]#converting your dict to list
print(pairs)

#iterate ur list and convert as json
for x in pairs:
    print("\n after converting: \n\t",json.dumps(x))#json like structure