Преобразование строки, представляющей словарь, в сам словарь
Как я могу преобразовать строковое представление словаря, такое как следующая строка, в словарь (dict
)?
s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
Я предпочитаю не использовать eval
. Какие другие методы я могу использовать?
5 ответ(ов)
Для преобразования строки JSON в объект Python в виде словаря, вы можете использовать функцию json.loads
. Вот пример:
import json
# Исходная строка JSON
h = '{"foo":"bar", "foo2":"bar2"}'
# Преобразование строки JSON в словарь
d = json.loads(h)
# Вывод результата
print(d) # {u'foo': u'bar', u'foo2': u'bar2'}
print(type(d)) # <type 'dict'>
В этом случае d
будет словарём Python, содержащим ключи 'foo'
и 'foo2'
с соответствующими значениями. Обратите внимание, что в Python 2 строки имеют префикс u
для обозначения юникода, а в Python 3 этого префикса нет, и все строки по умолчанию являются строками юникода.
Для подведения итогов:
import ast, yaml, json, timeit
descs = ['короткая строка', 'длинная строка']
strings = ['{"809001":2,"848545":2,"565828":1}', '{"2979":1,"30581":1,"7296":1,"127256":1,"18803":2,"41619":1,"41312":1,"16837":1,"7253":1,"70075":1,"3453":1,"4126":1,"23599":1,"11465":3,"19172":1,"4019":1,"4775":1,"64225":1,"3235":2,"15593":1,"7528":1,"176840":1,"40022":1,"152854":1,"9878":1,"16156":1,"6512":1,"4138":1,"11090":1,"12259":1,"4934":1,"65581":1,"9747":2,"18290":1,"107981":1,"459762":1,"23177":1,"23246":1,"3591":1,"3671":1,"5767":1,"3930":1,"89507":2,"19293":1,"92797":1,"32444":2,"70089":1,"46549":1,"30988":1,"4613":1,"14042":1,"26298":1,"222972":1,"2982":1,"3932":1,"11134":1,"3084":1,"6516":1,"486617":1,"14475":2,"2127":1,"51359":1,"2662":1,"4121":1,"53848":2,"552967":1,"204081":1,"5675":2,"32433":1,"92448":1}']
funcs = [json.loads, eval, ast.literal_eval, yaml.load]
for desc, string in zip(descs, strings):
print('***', desc, '***')
print('')
for func in funcs:
print(func.__module__ + ' ' + func.__name__ + ':')
%timeit func(string)
print('')
Результаты:
*** короткая строка ***
json.loads:
4.47 µs ± 33.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
builtins eval:
24.1 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
ast.literal_eval:
30.4 µs ± 299 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
yaml.load:
504 µs ± 1.29 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
*** длинная строка ***
json.loads:
29.6 µs ± 230 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
builtins eval:
219 µs ± 3.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ast.literal_eval:
331 µs ± 1.89 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
yaml.load:
9.02 ms ± 92.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Вывод: рекомендуется использовать json.loads.
Если строку всегда можно доверять, вы можете использовать eval
(или воспользоваться literal_eval
, как предложено; это безопасно независимо от содержания строки). В противном случае вам понадобится парсер. JSON-парсер (например, simplejson) сработает, если данные всегда соответствуют формату JSON.
Если у вас есть задача по чтению текстового файла размером 156 Мб и вам нужно преобразовать его в словарь, я рекомендую использовать библиотеку json
, а не ast
.
Проблема в том, что ast
потребляет слишком много памяти и работает медленно. На моем опыте, для превращения файла с помощью ast
уходит около 5 минут, тогда как с json
этот процесс занимает всего 1 минуту и использует на 60% меньше памяти!
Поэтому для ваших нужд json
будет более оптимальным выбором. Вы можете использовать следующий код для чтения вашего файла:
import json
with open('your_file.txt', 'r') as file:
data = json.load(file)
Таким образом, вы сможете значительно сократить время выполнения и уменьшить потребление памяти.
Вы можете привести строку, содержащую пары ключ-значение, в формат словаря в Python с помощью следующего кода. Этот код сначала удаляет фигурные скобки, затем разбивает строку по запятой для получения пар ключ-значение и, наконец, создает словарь из этих пар. Вот пример решения:
string = "{'server1':'value','server2':'value'}"
# Убираем фигурные скобки
s = string.replace("{", "")
finalstring = s.replace("}", "")
# Разбиваем строку по запятой для получения пар ключ-значение
list = finalstring.split(",")
dictionary = {}
for i in list:
# Получаем ключи и значения отдельно для сохранения в словаре
keyvalue = i.split(":")
# Убираем одинарные кавычки
m = keyvalue[0].strip('\'')
m = m.replace("\"", "")
dictionary[m] = keyvalue[1].strip('"\'')
print(dictionary)
В результате выполнения этого кода вы получите словарь, где ключами будут 'server1' и 'server2', а значениями - соответствующие им значения. Обратите внимание, что в Python 3 необходимо использовать print(dictionary)
вместо print dictionary
для корректного вывода.
Есть ли в Python метод подстроки 'contains' для строк?
Как преобразовать строку в int в Java?
Преобразование списка словарей в DataFrame pandas
Как получить имя функции в виде строки?
Вывод строки в текстовый файл