简体   繁体   中英

Convert string to dictionary format with boolean key-value pair

I was converting the string to python dictionay thru ast.literal_eval() . The string contains boolean values so the ast.literal_eval() getting ValueError .

From googling, I found that I have to add the statement ast.literal_eval(json.dumps(json.loads(data))) to handle boolen data.

But, I'm still getting the same error.

Here is the code snippet:

#!/usr/bin/python
import sys
import os
import ast
import json

def main(argv):
    data = argv[1]
    print(argv[1])

    crldix = ast.literal_eval(json.dumps(json.loads(data)))

    for drive in crldix['files']:
        print("|{}|{}|".format(drive['name'], drive['boolkey']))

    return 0

if __name__ == "__main__":
    retval = main(sys.argv)
    exit(retval)

#eof

Output:

./test.py '{  "files": [   {  "name": "filename",    "boolkey": false  }  ] } '

Traceback (most recent call last):
  File "./test.py", line 20, in <module>
    retval = main(sys.argv)
  File "./test.py", line 12, in main
    crldix = ast.literal_eval(json.dumps(json.loads(data)))
  File "/usr/lib/python2.7/ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python2.7/ast.py", line 63, in _convert
    in zip(node.keys, node.values))
  File "/usr/lib/python2.7/ast.py", line 62, in <genexpr>
    return dict((_convert(k), _convert(v)) for k, v
  File "/usr/lib/python2.7/ast.py", line 60, in _convert
    return list(map(_convert, node.elts))
  File "/usr/lib/python2.7/ast.py", line 63, in _convert
    in zip(node.keys, node.values))
  File "/usr/lib/python2.7/ast.py", line 62, in <genexpr>
    return dict((_convert(k), _convert(v)) for k, v
  File "/usr/lib/python2.7/ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

ast.literal_eval(json.dumps(json.loads(data))) is superfluous and redundant (see what I did here?)

json.loads already returns a dictionary, so there's no need to turn it back to a string then back to a dict with literal_eval .

Since json.loads('{ "files": [ { "name": "filename", "boolkey": false } ] } ') works, any problem you have is due to the way your terminal passes the string to sys.argv .

I don't know what OS/terminal you are using, but usually " is required in order to pass an argument with spaces. This will mean that you have to escape the other " in the string.

For example, on Windows, executing

import sys
import json

print(json.loads(sys.argv[1]))

In the following way (note the \\ used for escaping)

python test.py "{ \"files\": [   {  \"name\": \"filename\",    \"boolkey\": false  }  ] } "

works, outputting:

{'files': [{'name': 'filename', 'boolkey': False}]}

Another approach, without the need to escape " :

import sys
import json

print(json.loads(sys.argv[1].replace("'", '"')))

Then executing

python test.py "{  'files': [   {  'name': 'filename',    'boolkey': false  }  ] }"

works just as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM