Convert a Python string without quotes to dictionary
Question:
I need to convert a Python string (without quotes inside the string) to a dictionary. The string has the right format, but miss the quotes in each sub-string.
Example:
a_string = "{Name: 2, Test: 52, Number: 150}"
Answers:
import yaml
d = yaml.safe_load("{Name: 2, Test: 52, Number: 150}")
print(d)
# {'Name': 2, 'Test': 52, 'Number': 150}
Bear in mind however the possible implications of YAML syntax, eg. a NO
in the string would be interpreted as boolean False
.
IF you don’t want to use a YAML parser, AND can be sure that the format of the string will be as shown in your example, you can also do it with only builtin functions:
s = "{Name: 2, Test: 52, Number: 150}"
s1 = s[1:-1].split(", ")
d = {}
for item in s1:
k, v = item.split(": ")
d[k] = int(v) if v.isnumeric() else v
If your actual format is really as simple as your example, it’s not too hard to do:
>>> a_string = "{Name: 2, Test: 52, Number: 150}"
>>> cleaned = a_string.strip().lstrip('{').rstrip('}')
>>> cleaned
'Name: 2, Test: 52, Number: 150'
>>> pairs = [part.split(':') for part in cleaned.split(',')]
>>> pairs
[['Name', ' 2'], [' Test', ' 52'], [' Number', ' 150']]
>>> {pair[0].strip(): int(pair[1].strip()) for pair in pairs}
{'Name': 2, 'Test': 52, 'Number': 150}
If it’s more complex, or may become more complex in the future, I would recommend a YAML or JSON5 parser instead.
first you somehow need to convert your keys to strings (or anything other than just text). e.g. from
"{Name: 2, Test: 52, Number: 150}"
to
"{'Name': 2, 'Test': 52, 'Number': 150}"
then you can use the ast module
>>> import ast
>>> ast.literal_eval("{'Name': 2, 'Test': 52, 'Number': 150}")
{'Name': 2, 'Test': 52, 'Number': 150}
If keys are string and values are int, You can use regex
and replace key
with "key"
then use ast.literal_eval
or json.loads
.
import re
import ast
import json
a_string = "{Name: 2, Test: 52, Number: 150}"
res = re.sub(r'([a-zA-Z]+)', r'"1"', a_string) # Name -> "Name"
ast.literal_eval(res)
json.loads(res)
# {'Name': 2, 'Test': 52, 'Number': 150}
If the string is always in the exact format as your example, then the dictionary could be created with a one-liner using dictionary comprehension and some simple string methods (no imports required):
a_string = "{Name: 2, Test: 52, Number: 150}"
a_dict = {key: val for key, val in [item.split(': ') for item in a_string[1:-1].split(', ')]}
Result:
{'Name': '2', 'Test': '52', 'Number': '150'}
Or, to get integer values (not sure from your question if that’s needed or not):
a_dict = {key: int(val) for key, val in [item.split(': ') for item in a_string[1:-1].split(', ')]}
Result:
{'Name': 2, 'Test': 52, 'Number': 150}
I need to convert a Python string (without quotes inside the string) to a dictionary. The string has the right format, but miss the quotes in each sub-string.
Example:
a_string = "{Name: 2, Test: 52, Number: 150}"
import yaml
d = yaml.safe_load("{Name: 2, Test: 52, Number: 150}")
print(d)
# {'Name': 2, 'Test': 52, 'Number': 150}
Bear in mind however the possible implications of YAML syntax, eg. a NO
in the string would be interpreted as boolean False
.
IF you don’t want to use a YAML parser, AND can be sure that the format of the string will be as shown in your example, you can also do it with only builtin functions:
s = "{Name: 2, Test: 52, Number: 150}"
s1 = s[1:-1].split(", ")
d = {}
for item in s1:
k, v = item.split(": ")
d[k] = int(v) if v.isnumeric() else v
If your actual format is really as simple as your example, it’s not too hard to do:
>>> a_string = "{Name: 2, Test: 52, Number: 150}"
>>> cleaned = a_string.strip().lstrip('{').rstrip('}')
>>> cleaned
'Name: 2, Test: 52, Number: 150'
>>> pairs = [part.split(':') for part in cleaned.split(',')]
>>> pairs
[['Name', ' 2'], [' Test', ' 52'], [' Number', ' 150']]
>>> {pair[0].strip(): int(pair[1].strip()) for pair in pairs}
{'Name': 2, 'Test': 52, 'Number': 150}
If it’s more complex, or may become more complex in the future, I would recommend a YAML or JSON5 parser instead.
first you somehow need to convert your keys to strings (or anything other than just text). e.g. from
"{Name: 2, Test: 52, Number: 150}"
to
"{'Name': 2, 'Test': 52, 'Number': 150}"
then you can use the ast module
>>> import ast
>>> ast.literal_eval("{'Name': 2, 'Test': 52, 'Number': 150}")
{'Name': 2, 'Test': 52, 'Number': 150}
If keys are string and values are int, You can use regex
and replace key
with "key"
then use ast.literal_eval
or json.loads
.
import re
import ast
import json
a_string = "{Name: 2, Test: 52, Number: 150}"
res = re.sub(r'([a-zA-Z]+)', r'"1"', a_string) # Name -> "Name"
ast.literal_eval(res)
json.loads(res)
# {'Name': 2, 'Test': 52, 'Number': 150}
If the string is always in the exact format as your example, then the dictionary could be created with a one-liner using dictionary comprehension and some simple string methods (no imports required):
a_string = "{Name: 2, Test: 52, Number: 150}"
a_dict = {key: val for key, val in [item.split(': ') for item in a_string[1:-1].split(', ')]}
Result:
{'Name': '2', 'Test': '52', 'Number': '150'}
Or, to get integer values (not sure from your question if that’s needed or not):
a_dict = {key: int(val) for key, val in [item.split(': ') for item in a_string[1:-1].split(', ')]}
Result:
{'Name': 2, 'Test': 52, 'Number': 150}