String with backslashes to dictionary - python

I have the following string:
txt = "{\'legs_a\': 1,\'legs_b\': 0,\'score_a\': 304,\'score_b\': 334,\'turn\': B,\'i\': 2,\'z\': 19}"
When I print it, I see the below output in my console
{'legs_a': 1,'legs_b': 0,'score_a': 304,'score_b': 334,'turn': B,'i': 2,'z': 19}
I want to make a dictionary of the string by using ast.literal_eval()
import ast
d = ast.literal_eval(txt)
This yields the following error:
{ValueError}malformed node or string: <_ast.Name object at
0x7fb8b8ab4fa0>
Please explain what's going wrong? How can I make a dictionary from the string? Thanks

B is an undefined variable or unquoted string.
try:
txt = "{\'legs_a\': 1,\'legs_b\': 0,\'score_a\': 304,\'score_b\': 334,\'turn\': \'B\',\'i\': 2,\'z\': 19}"
d = ast.literal_eval(txt)
print(d)
Output:
{'legs_a': 1, 'legs_b': 0, 'score_a': 304, 'score_b': 334, 'turn': 'B', 'i': 2, 'z': 19}
Note if you wanted to deserialze the JSON string using json.loads() function then you would need to replace single quotes with double quotes.
data = json.loads(txt.replace("'", '"'))

Related

How to convert a string dictionary to dictionary in python?

I have dictionary in form of string -
dict_in_str = '{"name":"wrong_answers","y":8,"color": colorForSections["wrong_answers"]}'
I have tried both, the json.loads(dict_in_str) and ast.literal_eval(dict_in_str) methods.
But both of them are giving
json.decoder.JSONDecodeError: Expecting value: line 1 column 40 (char 39)
and
ValueError: malformed node or string: <_ast.Subscript object at 0x02082B20>
respectively. On forums and tutorials I have looked upon these methods seems to work.
As mentioned by deceze and matszwejca, he issue is your value in your last part, "color": colorForSections["wrong_answers"]. It can't evaluate the value of 'colorForSections["wrong_answers"]' because it's in a string. When you run loads() on it, it can't convert it to any known type (I'm assuming that's what's going on, egg on my face if not). Try passing in the key string ("wrong_answers") and then retrieving the value from colorForSections after you run loads() on the string. Something like:
dict_in_str = '{"name":"wrong_answers","y":8,"color": "wrong_answers"}'
x = json.loads(dict_in_str)
color = colorForSections[x['color']]
you can replace and split into list and then convert into dict.
dict_in_str = '{"name":"wrong_answers","y":8,"color":
colorForSections["wrong_answers"]}'
data_lst = dict_in_str.replace("'", '').replace('"', '').replace('{',
'').replace('}', '').replace(':', ',').split(',')
lst = [i.strip() for i in data_lst if i.strip()]
result = {lst[i]: lst[i + 1] for i in range(0, len(lst), 2)}
print(result)
print(type(result))
>>> {'name': 'wrong_answers', 'y': '8', 'color': 'colorForSections[wrong_answers]'}
<class 'dict'>

Python JSON change single quotes to double quotes leave in-string quotes alone

We have the following dataframe:
import pandas as pd
import numpy as np
import json
from json import JSONDecodeError
json_as_str_list = [
"[{'key1': 312, 'name': 'Simple name'}]",
"[{'key1': 981, 'name': 'Name n' quote'}]",
np.nan
]
d = {'json_as_str': json_as_str_list}
df = pd.DataFrame(data=d)
json_as_str
0 [{'key1': 312, 'name': 'Simple name'}]
1 [{'key1': 981, 'name': 'Name n' quote'}]
2 NaN
After the import json_as_str column is a list of strings but I want it to be a list of JSON objects. I've written a function which should return a list of empty JSON objects given a string or an empty list given a np.nan:
def convert_to_JSON_helper(json_str):
if isinstance(json_str, str):
json_str = json_str.replace("'", '"')
try:
return json.loads(json_str)
except JSONDecodeError:
print(json_str)
return []
else:
return []
Current implementation doesn't handle in-string single quotes (as in the second row of the dataframe). How should I modify the function so that it works as expected?
The current output I get while using df['json_as_str'].apply(convert_to_JSON_helper):
0 [{'key1': 312, 'name': 'Simple name'}]
1 []
2 []
Name: json_as_str, dtype: object
The output I'd like to get:
0 [{'key1': 312, 'name': 'Simple name'}]
1 [{'key1': 981, 'name': 'Name n' quote'}]
2 []
Name: json_as_str, dtype: object
The problem is not the function but the string. You typed a \ to quote the single quote, but it was plain useless because a single \ in a string quotes the following character (here the quote) and let it go in the string. Demo:
>>> a = " a 'b' 'c\'d' "
>>> a
" a 'b' 'c'd' "
The back slash has just be eaten in the string.
Anyway you should not try to convert quotes in a general way. Because of all the possible corner cases, you will have to build a dedicated (and complex) parser. So my advice is that you should just insert a correct JSON string in your dataframe.
Here is the convert a string (with single ') to dict.
import ast
data = ast.literal_eval("{'a' : 12, 'c' : 'd'}")
print(data)
print(type(data))
output
{'a': 12, 'c': 'd'}
<type 'dict'>

python split string into multiple delimiters and put into dictionary

i have the below string that i am trying to split into a dictionary with specific names.
string1 = "fdsfsf:?x=klink:apple&nn=specialtime&tr=instruction1&tr=instruction2&tr=instruction3"
what I am hoping to obtain is:
>>> print(dict)
{'namy_names': 'specialtime', 'tracks': ['instruction1', 'instruction2', 'instruction3']}
i'm quite new to working with dictionaries, so not too sure how it is supposed to turn out.
I have tried the below code, but it only provides instruction1 instead of the full list of instructions
delimiters = ['&nn', '&tr']
values = re.split('|'.join(delimiters), string1)
values.pop(0) # remove the initial empty string
keys = re.findall('|'.join(delimiters), string1)
output = dict(zip(keys, values))
print(output)
Use url-parsing.
from urllib import parse
url = "fdsfsf:?x=klink:apple&nn=specialtime&tr=instruction1&tr=instruction2&tr=instruction3"
d = parse.parse_qs(parse.urlparse(url).query)
print(d)
Returns:
{'nn': ['specialtime'],
'tr': ['instruction1', 'instruction2', 'instruction3'],
'x': ['klink:apple']}
And from this point, if necessary..., you would simply have to rename and pick your vars. Like this:
d = {
'namy_names':d.get('nn',['Empty'])[0],
'tracks':d.get('tr',[])
}
# {'namy_names': 'specialtime', 'tracks': ['instruction1', 'instruction2', 'instruction3']}
This looks like url-encoded data, so you can/should use urllib.parse.parse_qs:
import urllib.parse
string1 = "fdsfsf:?x=klink:apple&nn=specialtime&tr=instruction1&tr=instruction2&tr=instruction3"
dic = urllib.parse.parse_qs(string1)
dic = {'namy_names': dic['nn'][0],
'tracks': dic['tr']}
# result: {'namy_names': 'specialtime',
# 'tracks': ['instruction1', 'instruction2', 'instruction3']}

Python Convert string to dict

I have a string :
'{tomatoes : 5 , livestock :{cow : 5 , sheep :2 }}'
and would like to convert it to
{
"tomatoes" : "5" ,
"livestock" :"{"cow" : "5" , "sheep" :"2" }"
}
Any ideas ?
This has been settled in 988251
In short; use the python ast library's literal_eval() function.
import ast
my_string = "{'key':'val','key2':2}"
my_dict = ast.literal_eval(my_string)
The problem with your input string is that it's actually not a valid JSON because your keys are not declared as strings, otherwise you could just use the json module to load it and be done with it.
A simple and dirty way to get what you want is to first turn it into a valid JSON by adding quotation marks around everything that's not a whitespace or a syntax character:
source = '{tomatoes : 5 , livestock :{cow : 5 , sheep :2 }}'
output = ""
quoting = False
for char in source:
if char.isalnum():
if not quoting:
output += '"'
quoting = True
elif quoting:
output += '"'
quoting = False
output += char
print(output) # {"tomatoes" : "5" , "livestock" :{"cow" : "5" , "sheep" :"2" }}
This gives you a valid JSON so now you can easily parse it to a Python dict using the json module:
import json
parsed = json.loads(output)
# {'livestock': {'sheep': '2', 'cow': '5'}, 'tomatoes': '5'}
What u have is a JSON formatted string which u want to convert to python dictionary.
Using the JSON library :
import json
with open("your file", "r") as f:
dictionary = json.loads(f.read());
Now dictionary contains the data structure which ur looking for.
Here is my answer:
dict_str = '{tomatoes: 5, livestock: {cow: 5, sheep: 2}}'
def dict_from_str(dict_str):
while True:
try:
dict_ = eval(dict_str)
except NameError as e:
key = e.message.split("'")[1]
dict_str = dict_str.replace(key, "'{}'".format(key))
else:
return dict_
print dict_from_str(dict_str)
My strategy is to convert the dictionary str to a dict by eval. However, I first have to deal with the fact that your dictionary keys are not enclosed in quotes. I do that by evaluating it anyway and catching the error. From the error message, I extract the key that was interpreted as an unknown variable, and enclose it with quotes.

python 2.7 get rid of double backslashes

I have list with one string element, see below
>>> s
['{\\"SrcIP\\":\\"1.1.1.1\\",\\"DstIP\\":\\"2.2.2.2\\",\\"DstPort\\":\\"80\\"}']
want to get rid of these '\\' and have dict instead:
{"SrcIP":"1.1.1.1","DstIP":"2.2.2.2","DstPort":"80"}
It looks like JSON object. You can load it to dict by using json package, but first to get rid of list and \\ you can call s[0].replace('\\', '')
import json
my_dict = json.loads(s[0].replace('\\', ''))
You can try this:
import re
import ast
s = ['{\\"SrcIP\\":\\"1.1.1.1\\",\\"DstIP\\":\\"2.2.2.2\\",\\"DstPort\\":\\"80\\"}']
final_response = [ast.literal_eval(re.sub('\\\\', '', i)) for i in s][0]
Output:
{'SrcIP': '1.1.1.1', 'DstIP': '2.2.2.2', 'DstPort': '80'}
Just use string replace method :
list_1=['{\\"SrcIP\\":\\"1.1.1.1\\",\\"DstIP\\":\\"2.2.2.2\\",\\"DstPort\\":\\"80\\"}']
for i in list_1:
print(str(i).replace("\\",""))
Or you can do in one line:
print(str(list_1[0]).replace("\\",""))
output:
{"SrcIP":"1.1.1.1","DstIP":"2.2.2.2","DstPort":"80"}
s is a list with one text item, you could get your desired output as follows:
import ast
s = ['{\\"SrcIP\\":\\"1.1.1.1\\",\\"DstIP\\":\\"2.2.2.2\\",\\"DstPort\\":\\"80\\"}']
s_dict = ast.literal_eval(s[0].replace('\\', ''))
print s_dict
print s_dict['DstIP']
Giving you the following output:
{'SrcIP': '1.1.1.1', 'DstIP': '2.2.2.2', 'DstPort': '80'}
2.2.2.2
The Python function ast.litertal_eval() can be used to safely convert a string into a Python object, in this case a dictionary.

Categories