String to list python conversion - python

My input string looks like below
rule = "['xor',[{'asset':'pc','operator':'=','basis':true}]]"
Expected output
Output = ['xor',[{'asset':'pc','operator':'=','basis':true}]]
Also this is legacy code where I cannot do ast.literal_eval(rule) since basis has non-string value true which will throw error 'malformed string'
Any suggestions to do the same?
I tried with rule.strip('][').split(', '), but the output is not the expected format:
["'and',[{'fact':'waived','operator':'=','basis':true}"]

If you're OK with using eval, then you can define true in the environment to eval:
>>> rule = "['xor',[{'asset':'pc','operator':'=','basis':true}]]"
>>> print(eval(rule, {'true': True}))
['xor', [{'basis': True, 'asset': 'pc', 'operator': '='}]]

I think if you are not using tuples in those strings you could parse it as json.
import json
my_data = json.loads(my_string)
This will depend on the details of what you parsing though so buyer beware.

Related

Convert String of List to List in Python

I need to convert a string of list to List in Python. I have seen many of the similar questions but none of them works in this case.
I am passing some values through PostMan.
The key passing as a form data
Key = controls
value = [CR1,CR2]
I am fetching the data like this
c_list = self._kwargs['data'].get('controls', [])
print(c-list)
print(type(c-list))
I am getting the following o/p
[CC-2,CC-3]
<class 'str'>
But I need to get it as a list so I have tried the following method
import ast
c_list = self._kwargs['data'].get('controls', [])
res = ast.literal_eval(c_list)
But I am getting the following Error
malformed node or string: <_ast.Name object at 0x7f82966942b0>
You could simply do the following: strip the brackets and split on the commas
>>> s = "[CC-2,CC-3]"
>>> s.strip('[]').split(',')
['CC-2', 'CC-3']

Remove 'u' in JSON dictionary

I hope to use the dictionary load by json file. However, each item contains the character 'u'. I need to remove the 'u's.
I tried dumps, but it does not work.
import ast
import json
data= {u'dot',
u'dog',
u'fog',
u'eeee'}
res = eval(json.dumps(data))
print res
I hope to get: {
'dot',
'dog',
'fog,
'eeee'
}
But the error is:
TypeError: set([u'eeee', u'fog', u'dog', u'dot']) is not JSON serializable
The strings that start with u are unicode strings.
In your case, this has nothing to do with the problem:
data= {u'dot',
u'dog',
u'fog',
u'eeee'}
This creates a set and stores the results in the data variable. The json serializer can't handle sets since the json spec makes no mention of them. If you change this to be a list, the serializer can handle the data:
res = set(eval(json.dumps(list(data))))
Here I'm converting the data variable to a list to serialize it, then converting it back to a set to store the result in the res variable.
Alternatively, you can directly ask Python to convert the unicode strings to strings, using something like this:
res = {x.encode("utf-8") for x in data}
print(res)

grabbing an ID from string

I have a string where I'd like to grab the "id" number 12079500908. I am trying to use ast.literal_eval but received a ValueError: malformed string. Is there any other way to get the id number from the string below?
doc_request = urllib2.Request("https://api.box.com/2.0/search?query=SEARCHTERMS", headers=doc_headers)
doc_response = urllib2.urlopen(doc_request)
view_doc_response = doc_response.read()
doc_dict=ast.literal_eval(view_doc_response)
Edit
Output:
view_doc_response = '{"total_count":1,"entries":[{"type":"file","id":"12079500908","sequence_id":"1","etag":"1","sha1":"6887169228cab0cfb341059194bc980e1be8ad90","name":"file.pdf","description":"","size":897838,"path_collection":{"total_count":2,"entries":[{"type":"folder","id":"0","sequence_id":null,"etag":null,"name":"All Files"},{"type":"folder","id":"1352745576","sequence_id":"0","etag":"0","name":"Patient Files"}]},"created_at":"2013-12-03T10:23:30-08:00","modified_at":"2013-12-03T11:17:52-08:00","trashed_at":null,"purged_at":null,"content_created_at":"2013-12-03T10:23:30-08:00","content_modified_at":"2013-12-03T11:17:52-08:00","created_by":{"type":"user","id":"20672372","name":"name","login":"email"},"modified_by":{"type":"user","id":"206732372","name":"name","login":"email"},"owned_by":{"type":"user","id":"206737772","name":"name","login":"email"},"shared_link":{"url":"https:\\/\\/www.box.net\\/s\\/ymfslf1phfqiw65bunjg","download_url":"https:\\/\\/www.box.net\\/shared\\/static\\/ymfslf1phfqiw65bunjg.pdf","vanity_url":null,"is_password_enabled":false,"unshared_at":null,"download_count":0,"preview_count":0,"access":"open","permissions":{"can_download":true,"can_preview":true}},"parent":{"type":"folder","id":"1352745576","sequence_id":"0","etag":"0","name":"Patient Files"},"item_status":"active"}],"limit":30,"offset":0}'
calling doc_dict gives:
ValueError: malformed string
ast.literal_eval is for parsing valid Python syntax, what you have is JSON. Valid JSON looks a lot like Python syntax except that JSON can contain null, true, and false which are mapped to None, True, and False in Python when passed through a JSON decoder. You can use json.loads for this. The code might look something like this:
import json
doc_dict = json.loads(view_doc_response)
first_id = doc_dict['entries'][0]['id'] # with your data, should be 12079500908
Note that this assumes that you manually added the ... at the end of the string, presumably after shortening it. If that ... is actually in your code as well then you have invalid JSON and you will need to do some processing before it will work.

What does "str indices must be integers" mean?

I'm working with dicts in jython which are created from importing/parsing JSON. Working with certain sections I see the following message:
TypeError: str indices must be integers
This occurs when I do something like:
if jsondata['foo']['bar'].lower() == 'baz':
...
Where jsondata looks like:
{'foo': {'bar':'baz'} }
What does this mean, and how do I fix it?
As Marcelo and Ivo say, it sounds like you're trying to access the raw JSON string, without first parsing it into Python via json.loads(my_json_string).
You need to check the type for dict and existance of 'z' in the dict before getting data from dict.
>>> jsondata = {'a': '', 'b': {'z': True} }
>>> for key in jsondata:
... if type(jsondata[key]) is dict and 'z' in jsondata[key].keys() and jsondata[key]['z'] is True:
... print 'yes'
...
yes
>>>
or shorter one with dict.get
>>> jsondata = {'a': '', 'b': {'z': True}, 'c' :{'zz':True}}
>>> for key in jsondata:
... if type(jsondata[key]) is dict and jsondata[key].get('z',False):
... print 'yes'
...
yes
>>>
Actually your statement should raise SyntaxError: can't assign to function call due to the fact that you're missing a = and thus making an assignment instead of a check for equality.
Since I don't get the TypeError when running the code you've shown, I suppose that you first fix the missing = and after that check back on what the Stacktrace says.
But it might also be possible that your jsondata hasn't been decoded and therefore is still plain text, which would of course then raise the indexing error.

which is the best way to get the value of 'session_key','uid','expires'

i have a string
'''
{"session_key":"3.KbRiifBOxY_0ouPag6__.3600.1267063200-16423986","uid":164
23386,"expires":12673200,"secret":"sm7WM_rRtjzXeOT_jDoQ__","sig":"6a6aeb66
64a1679bbeed4282154b35"}
'''
how to get the value .
thanks
>>> import json
>>> s=''' {"session_key":"3.KbRiifBOxY_0ouPag6__.3600.1267063200-16423986","uid":16423386,"expires":12673200,"secret":"sm7WM_rRtjzXeOT_jDoQ__","sig":"6a6aeb66 64a1679bbeed4282154b35"} '''
>>> d=json.loads(s)
>>> d['session_key']
u'3.KbRiifBOxY_0ouPag6__.3600.1267063200-16423986'
>>> d['uid']
16423386
>>> d['expires']
12673200
>>> d['secret']
u'sm7WM_rRtjzXeOT_jDoQ__'
>>> d['sig']
u'6a6aeb66 64a1679bbeed4282154b35'
>>>
The string appears to be JSON.
import json
obj= json.loads( aString )
obj['session_key']
Or it could be a Python dict. Try
obj= eval(myString)
obj['session_key']
For a simple-to-code method, I suggest using ast.parse() or eval() to create a dictionary from your string, and then accessing the fields as usual. The difference between the two functions above is that ast.parse can only evaluate base types, and is therefore more secure if someone can give you a string that could contain "bad" code.

Categories