'How to convert a string to a dict from a list?
I have tried several ways to convert a dict-like str from a list to a dict, but cannot figure out how to interpret the error message correctly.
I have a list:
list = [(45, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': None, 'family': None}"), (12383, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Fagales', 'family': None}"), (12384, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Primulales', 'family': None}"), (12385, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Magnoliales', 'family': None}"), (12386, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Celastrales', 'family': None}")]
and want to convert the dict-like string into a dict, so I can access the values by key. I have tried:
test = (list[0][1]).replace("'", "\"")
dict(test)
but get the following error:
ValueError: dictionary update sequence element #0 has length 1; 2 is required
I also tried json.loads()
test2 = json.loads(test)
which returned:
JSONDecodeError: Expecting value: line 1 column 34 (char 33)
When I manually insert the string in the dict() function, the string successfully converts to a dict but not when using the list index. I would appreciate it if someone could explain why there is this difference and how I can convert the string directly into a dict.
Thanks for any help
Solution 1:[1]
You can use ast.literal_eval:
from ast import literal_eval
lst = [(45, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': None, 'family': None}"), (12383, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Fagales', 'family': None}"), (12384, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Primulales', 'family': None}"), (12385, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Magnoliales', 'family': None}"), (12386, "{'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': 'Celastrales', 'family': None}")]
output = [(num, literal_eval(dct_rep)) for num, dct_rep in lst]
print(output) # [(45, {'kingdom': 'Plantae', 'phylum': None, 'class': None, 'order': None, 'family': None}), ...]
print(output[0][1]['kingdom']) # Plantae
The list comprehension converts each dict representation into a true dict. After that you can access the data in a more natural way.
Solution 2:[2]
I would look at eval
test_dict = eval(list[0][1])
Note: This is not recommended in production code as this can run any python code
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | j1-lee |
| Solution 2 | AsynchronousGillz |
