EDIT: original version used eval
; new version uses literal_eval
from the standard ast
module.
If you have a string that represents a list of lists and want to turn that into a list,
- you can use the built-in Python function
eval()
(documentation). eval()
accepts a string as an argument and
evaluates it as a Python expression (after parsing the string). The
result of the evaluated expression is returned. If you do use eval
, you must be sure that the input source to eval
is trusted.
- you should (see discussion at end of post) use the function
literal_eval
(documentation) from the ast
module from the Python Standard Library.
This code does what you want using literal_eval
(eval
achieves the same effect but see note below).
from pprint import pprint
from ast import literal_eval
# import re
s = """
[
['apples',1,'04-07-2022','16:35'],
['oranges',5,'04-07-2022','18:35'],
['mangoes',10,'04-07-2022','16:00'],
['bananas',,'04-09-2022','11:00']
]
"""
s = s.replace(",,", ",'',")
# s = re.sub(r', *,', ",'',", s)
l = literal_eval(s)
pprint(l)
print(f"\nMango Quantity: {l[2][1]}")
The above replaces all occurrences of ',,'
with ",'',"
. If in the empty fields there are an arbitrary number of spaces between the commas (but nothing else), remove the s.replace
line and uncomment the two commented-out lines. Using re.sub
is a more general solution.
Output
[['apples', 1, '04-07-2022', '16:35'],
['oranges', 5, '04-07-2022', '18:35'],
['mangoes', 10, '04-07-2022', '16:00'],
['bananas', '', '04-09-2022', '11:00']]
Mango Quantity: 10
Safety Note
In many contexts, eval
and literal_eval
will achieve the same effect, as in this example. However, eval
is known to be potentially very dangerous. eval
takes its string argument, parses it and evaluates it as a Python expression. This can be an arbitrary Python expression. One concern is that Python permits users to access and delete system files (e.g. via the os
module). So a bad-actor may supply dangerous data that you feed into eval
, which could corrupt your system. This is why you need to be extra careful that you can trust the input source before supplying it to eval
. literal_eval
also accepts a string as an argument, but this is restricted to only contain (quote from literal_eval
doc cited above)
Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, None and Ellipsis. This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions[.]
In your case, you know that your string data represents a nested list that should only have numbers and strings as elements. So to be safe, use literal_eval
, which would not evaluate a non-allowed expression. So if your list had elements that would normally evaluate to something dangerous (which eval
would evaluate), literal_eval
would not evaluate it -- it is restricted to Python literal structures. In this case, even if you know and absolutely trust your input source, there is no harm in using literal_eval
instead.
Be safe!
Hope this helps. Please let me know if there are questions/concerns!