Convert Strings to Lists and Dictionaries in Python
In Python, you can use ast.literal_eval()
to convert strings (str
) into lists (list
), dictionaries (dict
), or other Python literal types.
This article also covers how to use the split()
method to split strings into lists using delimiters, and compares ast.literal_eval()
with eval()
and json.loads()
.
To join list elements back into a string, you can use the join()
method.
Split Strings into Lists Using Delimiters
When a string contains values separated by a specific character, you can split it into a list using the split()
method.
Here’s an example using a comma and space as the delimiter:
s = 'a, b, c'
l = s.split(', ')
print(l)
# ['a', 'b', 'c']
print(type(l))
# <class 'list'>
split()
returns a list of strings. Even if the string contains numbers, they are still treated as strings. To convert them to numeric types like int
or float
, use list comprehension:
s = '1-2-3'
l = s.split('-')
print(l)
# ['1', '2', '3']
print(type(l[0]))
# <class 'str'>
l = [int(c) for c in s.split('-')]
print(l)
# [1, 2, 3]
print(type(l[0]))
# <class 'int'>
Besides split()
, Python also provides methods like splitlines()
for splitting on line breaks, and re.split()
for splitting based on regular expressions. For more on these, see the following article:
Convert Strings to Lists and Dictionaries with ast.literal_eval()
To convert strings that are formatted like Python literals—such as lists, dictionaries, or sets—you can use ast.literal_eval()
.
Import the ast
module. It's included in the standard library, so no additional installation is required.
import ast
s = '["a", "b", "c"]'
l = ast.literal_eval(s)
print(l)
# ['a', 'b', 'c']
print(type(l))
# <class 'list'>
Because ast.literal_eval()
parses the string as a Python literal, it automatically converts elements like numbers and boolean values to their corresponding types.
s = '["x", 1, True]'
l = ast.literal_eval(s)
print(l)
# ['x', 1, True]
print(type(l[0]))
# <class 'str'>
print(type(l[1]))
# <class 'int'>
print(type(l[2]))
# <class 'bool'>
ast.literal_eval()
can convert the following literals:
The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans,
None
andEllipsis
. ast.literal_eval() — Abstract Syntax Trees — Python 3.13.3 documentation
Here are examples of converting a dictionary and a set from strings:
s = '{"key1": 1, "key2": 2}'
d = ast.literal_eval(s)
print(d)
# {'key1': 1, 'key2': 2}
print(type(d))
# <class 'dict'>
s = '{1, 2, 3}'
se = ast.literal_eval(s)
print(se)
# {1, 2, 3}
print(type(se))
# <class 'set'>
ast.literal_eval()
is especially useful when storing Python objects as strings in text files and loading them back later. If human readability is not necessary, using pickle might be a better option.
Differences Between eval()
and ast.literal_eval()
Python also provides a similar built-in function called eval()
.
The differences are as follows:
ast.literal_eval()
: Only evaluates strings that contain Python literals.eval()
: Evaluates any valid Python expression, including variables and operations.
For example, eval()
can compute arithmetic expressions, while ast.literal_eval()
cannot:
s = '["x", 1 + 10]'
print(eval(s))
# ['x', 11]
# print(ast.literal_eval(s))
# ValueError: malformed node or string
Likewise, eval()
can access previously defined variables:
a = 100
print(eval('[1, a]'))
# [1, 100]
# a = 100
# print(ast.literal_eval('[1, a]'))
# ValueError: malformed node or string
Because eval()
can execute arbitrary code, it poses security risks if used with untrusted input. In general, prefer ast.literal_eval()
when you only need to parse literals.
Differences Between json.loads()
and ast.literal_eval()
The json
module provides a function called json.loads()
that parses JSON-formatted strings into Python dictionaries and lists. It’s also part of the standard library:
import json
s = '{"key1": [1, 2, 3], "key2": "abc"}'
print(json.loads(s))
# {'key1': [1, 2, 3], 'key2': 'abc'}
print(ast.literal_eval(s))
# {'key1': [1, 2, 3], 'key2': 'abc'}
However, json.loads()
only accepts JSON-formatted strings. For example:
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested. https://www.json.org/json-en.html
ast.literal_eval()
supports Python-specific values like True
, False
, and None
, whereas json.loads()
does not:
s = '[True, False, None]'
# print(json.loads(s))
# JSONDecodeError: Expecting value:
print(ast.literal_eval(s))
# [True, False, None]
Conversely, true
, false
, and null
can be converted by json.loads()
but not by ast.literal_eval()
:
s = '[true, false, null]'
print(json.loads(s))
# [True, False, None]
# print(ast.literal_eval(s))
# ValueError: malformed node or string
Also, json.loads()
requires strings to be enclosed in double quotes "
according to JSON specifications, while ast.literal_eval()
allows single quotes '
, triple single quotes '''
, or triple double quotes """
according to Python string literal specifications:
s = "{'key1': 'abc', 'key2': '''xyz'''}"
# print(json.loads(s))
# JSONDecodeError: Expecting property name enclosed in double quotes
print(ast.literal_eval(s))
# {'key1': 'abc', 'key2': 'xyz'}
For working with JSON data, the json
module is usually the better choice. You can also use json.load()
to read from JSON files. For more on this, see the article below: