To convert a string to a dictionary in Python, use ast.literal_eval() when the text looks like a Python dict (single quotes, True, None), and json.loads() when it’s JSON. Both return a real dict:
import ast, json
ast.literal_eval("{'state': 'TX', 'total': 49.99}") # {'state': 'TX', 'total': 49.99}
json.loads('{"state": "TX", "total": 49.99}') # same dict
I tested these conversions on Python 3.12.5 from Command Prompt, feeding them made-up US customer orders.
The right tool depends on what the string looks like, so we’ll go format by format and finish with a safe helper.
Convert a Python dict string with ast.literal_eval()
A string like "{'customer': 'Emily Carter'}" usually comes from str(my_dict) or a log file. ast.literal_eval() reads it back, nested lists and booleans included:
import ast
text = "{'customer': 'Emily Carter', 'state': 'TX', 'balance': 1250.5, 'active': True, 'tags': ['pro', 'annual']}"
order = ast.literal_eval(text)
print(type(order))
print(order["customer"], order["tags"][0])
print(f"Balance: ${order['balance']:,.2f}")
Output:
<class 'dict'>
Emily Carter pro
Balance: $1,250.50

type() confirms a real dict, so keys, list items and the balance work right away.You can trust it because it only accepts literals, never function calls. Going the other way is covered in converting a dictionary to a string in Python.
Convert a JSON string to a dictionary with json.loads()
API responses use JSON: double quotes, true and null. json.loads() maps those to True and None, but a single-quoted Python string makes it fail:
import ast
import json
api_text = '{"customer": "James Miller", "total": 49.99, "paid": true, "coupon": null}'
data = json.loads(api_text)
print(data)
repr_text = "{'customer': 'James Miller', 'paid': True}"
try:
json.loads(repr_text)
except json.JSONDecodeError as err:
print("json.loads failed:", err)
print(ast.literal_eval(repr_text))
Output:
{'customer': 'James Miller', 'total': 49.99, 'paid': True, 'coupon': None}
json.loads failed: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
{'customer': 'James Miller', 'paid': True}

json.loads() rejects the single-quoted keys with a JSONDecodeError; literal_eval() reads the same text fine.Don’t swap the quotes with replace(); you’ll break names like O’Brien. Nested JSON, dates and JSON files are in my guide to converting a JSON string to a dictionary.
How do I convert a key=value string to a dictionary?
Text such as name=Olivia Brown; state=CO isn’t a literal, so split it yourself: on the pair separator, then on the first =, stripping spaces:
line = "name=Olivia Brown; city=Denver; state=CO; plan=pro; total=79.5"
record = {}
for pair in line.split(";"):
key, value = pair.split("=", 1) # maxsplit=1 keeps any '=' inside the value
record[key.strip()] = value.strip()
print(record)
record["total"] = float(record["total"])
print(f"{record['name']} owes ${record['total']:.2f}")
# one-liner for simple "key:value,key:value" text
codes = dict(item.split(":", 1) for item in "TX:Texas,CA:California,NY:New York".split(","))
print(codes)
Output:
{'name': 'Olivia Brown', 'city': 'Denver', 'state': 'CO', 'plan': 'pro', 'total': '79.5'}
Olivia Brown owes $79.50
{'TX': 'Texas', 'CA': 'California', 'NY': 'New York'}

total stays text until float() turns it into a number.You get strings from split(), so convert numbers yourself. More splitting options are in splitting a string by comma in Python, and extra spaces are handled in removing spaces from a string.
Convert a URL query string to a dictionary
For state=TX&plan=pro text from a URL, the standard library parses and decodes it. parse_qsl() gives pairs for dict(); parse_qs() keeps repeated keys:
from urllib.parse import parse_qs, parse_qsl, urlsplit
url = "https://shop.example.com/checkout?state=TX&plan=pro&total=49.99&tag=new&tag=sale"
query = urlsplit(url).query
print(dict(parse_qsl(query))) # one value per key; the last tag wins
print(parse_qs(query)) # every value kept in a list
Output:
{'state': 'TX', 'plan': 'pro', 'total': '49.99', 'tag': 'sale'}
{'state': ['TX'], 'plan': ['pro'], 'total': ['49.99'], 'tag': ['new', 'sale']}
Use parse_qs() when a key can repeat, like the two tag values here. Then a dictionary comprehension can convert the values.
Safely convert any string to a dict, and why not eval()
eval() works too, but it runs any code in the string, so I never use it on text I didn’t write. This helper tries JSON, then literal_eval(), and rejects the rest:
import ast
import json
def to_dict(text):
"""Turn JSON or a Python dict literal into a dict, or raise ValueError."""
try:
result = json.loads(text)
except json.JSONDecodeError:
try:
result = ast.literal_eval(text)
except (ValueError, SyntaxError) as err:
raise ValueError(f"not a dictionary string: {err}") from None
if not isinstance(result, dict):
raise ValueError(f"expected a dict, got {type(result).__name__}")
return result
samples = ['{"plan": "pro", "seats": 5}',
"{'plan': 'team', 'seats': 12}",
"__import__('os').getcwd()",
"[1, 2, 3]"]
for s in samples:
try:
print("OK ", to_dict(s))
except ValueError as err:
print("FAIL", err)
Output:
OK {'plan': 'pro', 'seats': 5}
OK {'plan': 'team', 'seats': 12}
FAIL not a dictionary string: malformed node or string on line 1: <ast.Call object at 0x000002216ACA4DD0>
FAIL expected a dict, got list

__import__ call is refused as a malformed node, and the list is rejected because it isn’t a dict.You need the isinstance() check because literal_eval() also returns lists. If you later need key-value pairs, see converting a dictionary to a list of tuples.
String to dictionary methods compared
| String looks like | Use | Watch out for |
|---|---|---|
{'a': 1, 'ok': True} | ast.literal_eval() | Returns any literal, so check for dict |
{"a": 1, "ok": true} | json.loads() | Single quotes raise JSONDecodeError |
a=1; b=2 | split() + dict() | Values stay strings |
a=1&b=2 | parse_qsl() / parse_qs() | Repeated keys |
You’ll probably want these next:
- Convert a string to JSON in Python
- Convert a string to an integer in Python
- Handle a KeyError with try/except in a dictionary
- Convert a dictionary to JSON in Python
Frequently asked questions
How do I convert a string to a dictionary in Python?
Use ast.literal_eval(s) for a Python-style dict string and json.loads(s) for a JSON string.
Why does json.loads fail on my dictionary string?
JSON needs double quotes. A str(dict) string uses single quotes, so read it with ast.literal_eval().
Is it safe to use eval() to convert a string to a dict?
No, it runs any code in the string. Use ast.literal_eval(), which raises ValueError on code.
How do I convert “key=value” text to a dictionary?
dict(p.split("=", 1) for p in s.split(";")), then strip spaces if needed.
How do I turn a URL query string into a dict?
Use dict(urllib.parse.parse_qsl(query)), or parse_qs(query) to keep repeated keys as lists.
Where is ast.literal_eval documented?
See ast.literal_eval() in the Python docs.
