Как превратить строку в словарь python
Словари в Python это структура данных вида «ключ-значение». То есть чтобы перевести строку в словарь, надо хотя бы описать условие что будет ключами, а что значениями.
Например, если мы хотим ключами сделать символы, а значениями их количество в строке, то можно воспользоваться Counter
from collections import Counter s = 'Hello, World!' Counter(s) # Counter()
Как из строки получить словарь (из str в dict)?

А почему не стоит? Пусть пишут кривой код и учатся на ошибках. А то все в программирование поперлись и всякую ерунду спрашивают, потому что лень почитать ошибки. Вот там json наверняка ругалась на кавычки.

Александр, eval не относится к бест практикам и красивому коду.

Даниил Чернов @dancha Автор вопроса
Хахаха, я и делал через eval, но я забыл что у меня переменная до этого еще одну обработку проходила.
Извините за лишний вопрос и спасибо за ответ)))
Влад Григорьев, Ох уж этот страшный eval, ох уж как он много вреда приносит, ужас
Все указанные решения работают в некоторых частных случаях и могут сломаться в любой момент.
В общем случае, нет стандартного способа получить строку в указанном топикстартером виде и синтаксис он не указал, поэтому я предполагаю, что это результат какой-то разрушающей операции типа str от питоновского объекта. Если речь идёт действительно об str, то он вполне способен сгенерировать довольно разные строки, которые будут ломать любой из указанных способов.
Например, вариант с ремлейсом ломается если внутри уже есть кавычки. Вариант с эвалом не стоит советовать, так как на определенных данных он может привести к исполнению стороннего кода. Вариант с literal_eval сломается на сложных объектах (а так как мы не знаем, как автор получил свою строку, можно допустить, что там может быть что угодно)
Влад Григорьев, да при чем тут красота. Обычная дыра в приложении.
javedimka, не понимаю ваш сарказм. Можете развернуть?
Tishka17, У меня в конфиге есть возможность задать питонье выражение/функцию которая потом выполняется exec`ом или eval`ом — если клиент захочет вызвать сегментейшен еррор или поломать приложение — то кто-будет виноват? «Дыра» в приложении или сам себе злобный Буратино (клиент)? Проблема не в eval, а в программистах которые его не там используют, если json парсится eval`ом в веб приложении и endpoint может дергать кто угодно — безусловно дыра. Если json парсится eval`ом во внутреннем скрипте препроцессинга миллионов записей для БД, что позволяет увеличить скорость обработки чуть ли не на 40% — это не зло и не дыра, это осознанное, и правильное решение.
javedimka,
Если у вас конфиг обрабатывается эвалом — это уже не конфиг, а скрипт. Соответственно, если ваша программа позволяет выполнять пользователю в ней произвольные скрипты, вы должны многое предусмотреть. Например, программа, работающая от рута скорее всего не должна исполнять скрипты заполненные обычным юзером, так как это будет повышение привилегий. Обычно конфиги программ же делают в любом текстовом формате как раз чтобы не дать простому юзеру своей ошибкой удалить все данные или сломать компьютер (да, евал может не просто вызвать сегфолт, а вызвать произвольную системнуюкоманду вполть до `rm -rf ~/*`)
Если json в базе эвалом парсится быстрее чем с помощью json — это довольно странно и, вероятно, вы делаете что-то не то. Мой простой тест выдал такие результаты на парсинге эталонного набора (меньше — лучше)
json - 1.034 ujson - 0.344 eval - 16.797
import json from timeit import timeit import ujson orig = ": list(range(i, i + 100)) for i in range(100)> data = json.dumps(orig) assert ujson.loads(data) == eval(data) n=1000 print(" json", timeit('json.loads(data)', globals=globals(), number=n)) print("ujson", timeit('ujson.loads(data)', globals=globals(), number=n)) print(" eval", timeit('eval(data)', globals=globals(), number=n))
Я не отрицаю, что eval действительно где-то может оказаться полезен именно для парсинга данных, но это должны быть данные правильным образом подготовленные, полученные из доверенного источника и, конечно, надо быть уверенным что это действительно нужная и не имеющая лучших альтернатив оптимизация
Предусматривать, конечно, нужно, например, скрипт запускать не из под рута
Результаты тестов удивительные, ничего не скажу. Сейчас проверить не могу ошибся ли я в своих высказываниях про скорость, т.к. оригинальный скрипт не был закомичен и впоследствии был переписан на go

Сергей Золотарёв @seregazolotaryow64
Этот вариант по преобразованию строки в словарь мне не помог;-(
Перед вами код:
import ast import json nmq = input() nm = nmq.split(" ") n = int(nm[0]) m = int(nm[1]) feedqueres = [] feedform = <> feed = <> for i in range(n): feeddata = str(input()) feedqueres.append(feeddata) feedform.update(>) for i in range(len(feedqueres)): data = json.loads(feedqueres[i]) feedform['offers'].update(ast.literal_eval(data['offers'])) feed.update(>) for i in range(m): readydata = feedform['offers'][i] feed['offers'].update(ast.literal_eval(readydata)) print(json.dumps(feed))
На который поругался компилятор:
Traceback (most recent call last): File "main.py", line 24, in feedform['offers'].update(ast.literal_eval(data['offers'])) File "/usr/lib/python3.8/ast.py", line 99, in literal_eval return _convert(node_or_string) File "/usr/lib/python3.8/ast.py", line 98, in _convert return _convert_signed_num(node) File "/usr/lib/python3.8/ast.py", line 75, in _convert_signed_num return _convert_num(node) File "/usr/lib/python3.8/ast.py", line 66, in _convert_num _raise_malformed_node(node) File "/usr/lib/python3.8/ast.py", line 63, in _raise_malformed_node raise ValueError(f'malformed node or string: ') ValueError: malformed node or string: [, ]
Как создать словарь из строки
Для присваивания индексов к элементам коллекций удобно использовать функцию enumerate :
str1 = "Python" dic = print(dic) #
Отслеживать
ответ дан 20 авг 2021 в 13:02
76.9k 6 6 золотых знаков 56 56 серебряных знаков 123 123 бронзовых знака
В питоне походу при желании можно вообще любой код написать в одну строчку))
20 авг 2021 в 13:04
@denisnumb, 😀 В ответе strawdog еще проще сделано 🙂
20 авг 2021 в 13:05
Первый раз работаю с функцией enumerate. Спасибо за помощь!
20 авг 2021 в 13:23
@python_prog, пожалуйста 🙂
20 авг 2021 в 13:31
Я бы сделал так:
str1 = "Python" dic = <> for item, value in enumerate(str1): # item - индекс значения из строки(счет с 0), value - символ из str1 dic[item + 1] = value # ключ словаря - индекс + 1, значение ключа - символ строки print(dic)
Отслеживать
ответ дан 20 авг 2021 в 13:06
Tehnorobot Tehnorobot
2,140 1 1 золотой знак 4 4 серебряных знака 13 13 бронзовых знаков
У меня почему-то цикл for с двумя аргументами не работала, но наверное у меня другая ошибка была, сейчас всё работает. Спасибо!
20 авг 2021 в 13:26
@python_prog наверно, просто, enumerate пропустили.
20 авг 2021 в 13:28
Можно сделать все куда проще 🙂
К отдельным буквам строки ‘Python’ можно обращаться по индексам, как у списков. Например, str1[0] будем иметь значение первой буквы, то есть ‘P’
Таким образом, в цикле for от 1 до len(str1)+1 (чтобы нумерация в словаре шла с единицы) заполняем словарь
Но поскольку нумерация символов str1 начинается с 0 , в каждой итерации при обращении к отдельной букве нам нужно вычесть 1 из i
str1 = "Python" dic = <> for i in range(1, len(str1)+1): dic[i] = str1[i-1] print(dic)
Вывод:
Отслеживать
ответ дан 20 авг 2021 в 12:54
5,605 2 2 золотых знака 10 10 серебряных знаков 36 36 бронзовых знаков
Спасибо вам большое. Очень помогли! Не додумалась написать dic[i] = str1[i-1]. ☺
20 авг 2021 в 12:59
Кст, думаю, действительно лучше range(len(str)) , а вот в ключ записывать с +1
20 авг 2021 в 13:06
Да, пожалуй так
20 авг 2021 в 13:09
- python
- python-3.x
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Как преобразовать строковое представление словаря в словарь в Python
Иногда при работе с Python возникает необходимость преобразовать строковое представление словаря обратно в словарь. Представим, что есть строка, которая представляет собой словарь:
Цель — преобразовать эту строку обратно в словарь Python.
Одним из способов сделать это было бы использование функции eval() , однако это может быть небезопасно, потому что eval() может выполнять произвольный код. Так что лучше избегать его использования, если это возможно.
Более безопасным вариантом является использование модуля ast и его функции literal_eval() . В отличие от eval() , literal_eval() обрабатывает только простые литералы Python.
Вот как это может быть выполнено:
import ast s = "" d = ast.literal_eval(s)
После выполнения этих строк, d будет словарем Python, который можно использовать как обычный словарь:
print(d) # Output:
Таким образом, если есть необходимость преобразовать строковое представление словаря обратно в словарь и при этом не использовать eval() , то функция literal_eval() из модуля ast будет отличным выбором.