Convert a python dict to a string and back
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Converting a Python dictionary to a string and back is a common task for data storage, network transmission, and logging. The two main approaches are json.dumps() / json.loads() for JSON-compatible data, and str() / ast.literal_eval() for Python-literal representations. JSON is the standard choice for interoperability with other languages and systems, while ast.literal_eval() handles Python-specific types that JSON cannot represent.
Method 1: json.dumps() and json.loads()
json.dumps() serializes a dict to a JSON-formatted string. json.loads() parses a JSON string back into a dict. This is the recommended approach for most use cases.
Method 2: str() and ast.literal_eval()
str() converts a dict to its Python literal representation. ast.literal_eval() safely evaluates that string back into a Python object. Unlike eval(), literal_eval only accepts literals (strings, numbers, tuples, lists, dicts, booleans, None) and cannot execute arbitrary code.
Method 3: repr() and ast.literal_eval()
repr() is similar to str() but is more explicit about escaping, making it more reliable for round-tripping.
JSON vs ast.literal_eval Comparison
| Feature | json | str + ast.literal_eval |
| Interoperability | Works across languages | Python only |
| Tuple support | Converts to list | Preserved |
| Set support | Not supported | Preserved |
| None handling | Converts to null | Preserved as None |
| Speed | Faster (C implementation) | Slower (parser) |
| Safety | Safe | Safe (no code execution) |
Handling Non-Serializable Types
File Storage
Note the distinction: json.dumps() / json.loads() work with strings, while json.dump() / json.load() work with file objects.
Common Pitfalls
- Using
eval()instead ofast.literal_eval():eval()executes arbitrary Python code, making it a security vulnerability.ast.literal_eval()only parses literals and is safe to use with untrusted input. - JSON converting tuples to lists:
json.dumps((1, 2, 3))produces"[1, 2, 3]", andjson.loadsreturns a list. If tuple identity matters, useast.literal_evalwithstr()or convert lists back to tuples after loading. - JSON converting integer keys to strings:
json.dumps({1: "a"})produces'{"1": "a"}'because JSON keys must be strings. Afterjson.loads, the key is"1"(string), not1(int). - Single quotes in JSON strings: JSON requires double quotes.
json.loads("{'key': 'value'}")raisesJSONDecodeError. Usejson.loads('{"key": "value"}')orast.literal_evalfor Python-style strings. - Non-serializable objects in
json.dumps: Passing a dict containingdatetime,set,bytes, or custom objects raisesTypeError. Use a customJSONEncodersubclass or convert these types before serialization.
Summary
- Use
json.dumps()/json.loads()for standard dict-to-string conversion — it is fast, safe, and interoperable - Use
str()/ast.literal_eval()when you need to preserve Python-specific types like tuples and sets - Never use
eval()to parse untrusted strings — always useast.literal_eval()orjson.loads() - JSON keys are always strings — integer keys become string keys after round-tripping
- Use
json.dump()/json.load()(no "s") for reading and writing JSON files directly - Implement a custom
JSONEncoderto handledatetime,set, and other non-serializable types

