Преобразовать строку в словарь

Каков один из питонических способов преобразования строки со встроенным форматированием словаря в словарь? Я пробовал регулярное выражение, но это не совсем так, чтобы быть правильным форматированием.

string_dictable ="{""name"":""Andrew,Carnegie"",""short_name"":""And,Car"",
""YOB"":1835,""Citizen"":""Scottish""}"

Все лишние цитаты кажутся проблемой, и пока мне не удалось их обойти.

Мой ожидаемый результат:

dicted_string ={"name":"Andrew, Carnegie","short_name":"And,Car","YOB":1835,"Citizen":"Scottish"}

Я тоже пробовал

ast.literal_eval (string_dictable)

но безрезультатно.

Обновлено: Я не касался исходного форматирования, и, к сожалению, исходный вопрос не может быть уточнен или изменен. Тем не менее, спасибо всем за вклад. Как я уже сказал, решение с регулярным выражением дало мне это

{'{name': 'Andrew,Carnegie,short_name:And,Car,YOB:1835,Citizen:Scottish}'}

и это не совсем то, над чем мне нужно было поработать.

Где вы вообще взяли эту строку? Разве вы не можете сделать это лучше из источника?

nosklo 10.08.2018 16:34

вы можете попробовать ast.literal_eval(yourstring.replace('""', '"'))

nosklo 10.08.2018 16:35

Похоже, кто-то думает, что строки Python ускользают от символов ", удваивая их. Это не так. Строковые литералы, которые находятся рядом друг с другом, автоматически объединяются, поэтому "abc""123" оценивается как "abc1123".

Patrick Haugh 10.08.2018 16:37

Вы получаете это из какого-то другого файла в этом формате или записываете эти строковые литералы в файл python? Если вы получаете их из файла, можем ли мы увидеть пару строк этого файла?

Patrick Haugh 10.08.2018 16:47
1
4
220
4

Ответы 4

В вашем string_dictable есть синтаксические ошибки (там две кавычки вместо одной). Попробуй это:

string_dictable = '{"name":"Andrew,Carnegie","short_name":"And,Car", "YOB":1835,"Citizen":"Scottish"}'
dict = ast.literal_eval (string_dictable)

цитаты являются частью форматирования. это не ошибка

Benyam 10.08.2018 16:39

Хорошо, заменив этот ответ почти полностью, но оставив оригинал ниже.

Итак, из того, что я собрал, текущая проблема заключается в том, что OP имеет текстовый файл со следующим внутри него: "{""name"":""Andrew,Carnegie"",""short_name"":""And,Car"",""YOB"":1835,""Citizen"":""Scottish""}"

Итак, при чтении файла в python должно произойти следующее:

f = open('stack.txt','r+') #I've made a text file with the above inside of it named stack.txt
for i in f:
    fixed = str(i).replace('"', "'")
    fixed = fixed.replace("''", '"')
    d = eval(fixed)

d теперь будет отформатирован как таковой: {"name":"Andrew,Carnegie","short_name":"And,Car","YOB":1835,"Citizen":"Scottish"}

Первое исправление меняет его на: '{''name'':''Andrew,Carnegie'',''short_name'':''And,Car'',''YOB'':1835,''Citizen'':''Scottish''}'

Второй прогон устраняет проблему: '{"name":"Andrew,Carnegie","short_name":"And,Car","YOB":1835,"Citizen":"Scottish"}'

Наконец, eval превращает его в словарь.

ЗАПИСЬ ИГНОРИРОВАТЬ

Очень легко использовать eval(string)

Вот небольшой макет, который я сделал. Обязательно используйте похожий синтаксис, и все будет в порядке.

>>> String = '{"name":"Andrew,Carnegie","short_name":"And,Car", "YOB":1835,"Citizen":"Scottish"}'
>>> dictionary = eval(String)
>>> dictionary['name']
'Andrew,Carnegie'
>>> 

Обновлено: Не уверен, почему это до сих пор опускается, метод eval() - это самый простой способ преобразовать строку в словарь, если ввод не может быть изменен OP, я могу работать над решением, но проблема в том, что исходный строка даже не может быть прочитана Python:

>>> string_dictable ="{""name"":""Andrew,Carnegie"",""short_name"":""And,Car"",
""YOB"":1835,""Citizen"":""Scottish""}"
SyntaxError: EOL while scanning string literal

Поэтому, если он не хранится в текстовом файле, и переменная не может быть изменена на входе, с точки зрения Python мало что можно сделать.

Обратите внимание, что string_dictable в приведенном выше значении оценивается как '{name:Andrew,Carnegie,short_name:And,Car,YOB:1835,Citizen:S‌​cottish}'.

Patrick Haugh 10.08.2018 16:36

@PatrickHaugh Не уверен, к чему вы клоните, я отредактировал его синтаксис, чтобы он не ошибался. Если ему нужно изменить ввод, чтобы он работал, он должен это прояснить.

J0hn 10.08.2018 16:38

@timgeb исходный синтаксис буквально невозможно обработать python, если только он не извлекается из файла (который OP не указал, как и почему он отформатирован как таковой), тогда ничего нельзя сделать.

J0hn 10.08.2018 16:44

@ J0hn строка представлена ​​здесь в исходном форматировании. Это часть файла, которым я не могу поделиться.

Benyam 10.08.2018 17:02

Тем не менее, это помогает понять, что вы извлекаете это из файла. Вы используете такой метод, как f = open("file.txt', "r"')? Кроме того, хранится ли он в текстовом файле с частью string_dictable =, или это просто испорченный словарь? Мне нужно ТОЧНО, как он хранится, чтобы я мог исправить это для вас.

J0hn 10.08.2018 17:06

@Benyam см. Выше

J0hn 10.08.2018 17:11

@ J0hn исходный файл имеет гораздо более вложенную структуру. Я упростил его до сегмента, который, если он будет решен, также будет использоваться для любого уровня вложенности. Кстати, оба формата в вашем вопросе одинаковы, и да, он изначально в этом формате. Я вообще не форматировал исходную строку.

Benyam 10.08.2018 17:17

@Benyam Хорошо, тогда см. Мой замененный ответ наверху для вашего решения.

J0hn 10.08.2018 17:38

@DYZ Из уст лошади: «Бывают случаи, когда вам нужно использовать eval или exec. Но они редки. Использование eval в вашем случае, безусловно, плохая практика. Я подчеркиваю плохую практику, потому что eval и exec часто используется не в том месте ". Если вы хотите проголосовать против меня, потому что я использовал eval (), тогда расскажите, как вы решите эту проблему, чтобы я мог избежать ее использования.

J0hn 13.08.2018 14:45
ast.literal_eval безопасен - и его достаточно для этой работы.
DYZ 13.08.2018 16:13

Просто замените "" на "и затем используйте eval (). Это довольно просто, вот так:

string_dictable ='{""name"":""Andrew,Carnegie"",""short_name"":""And,Car"",""YOB"":1835,""Citizen"":""Scottish""}'
string_dictable = string_dictable.replace('""','"')
d = eval(string_dictable)

d - допустимый словарь.

Если ввод задан как string_dictable ="{""name"":""Andrew,Carnegie"",""short_name"":""And,Car"", ""YOB"":1835,""Citizen"":""Scottish""}", то это решение не работает. Поскольку вы уже заменили внешний "на", что, по-видимому, неверно (см. Мой ответ, который был отклонен)

J0hn 10.08.2018 16:47

Немного странно, что за ответ проголосовали против. Решение кажется довольно простым и понятным, поскольку проблема заключается только в двойных кавычках.

Ildar Akhmetov 10.08.2018 16:48

@ J0hn but string_dictable = "{" "name" ":" "Эндрю, Карнеги" "," "short_name" ":" "And, Car" "," "YOB" ": 1835," "Citizen" ":" «Шотландский» «}» - неправильное выражение Python ... Это означает, что вопросы не имеют смысла.

Ildar Akhmetov 10.08.2018 16:49

Собственно, этот вопрос требует дополнительной информации о том, откуда поступает этот ввод и почему он так неверен. Вопрос, скорее всего, должен быть закрыт, так как его невозможно решить, используя текущую информацию.

J0hn 10.08.2018 16:51

@IldarAkhmetov Это является действительный оператор Python. Ты пробовал?

DYZ 11.08.2018 06:50

@DYZ Какое утверждение вы имеете в виду?

Ildar Akhmetov 11.08.2018 07:32

Первое заявление в исходном посте. То, что вы говорите, «не является правильным выражением Python».

DYZ 11.08.2018 08:41

Решение с использованием

json
module
import json
dicted_string = json.loads(string_dictable.replace('""','"')

Я не знаю элегантного способа обработки двойных двойных кавычек в исходной строке, иначе строка в основном имеет хороший формат json.

Если вы можете изменить источник своей строки, чтобы исключить двойные двойные кавычки (""), вы можете просто передать string_dictable в json.loads, чтобы получить словарь из строки.

Другие вопросы по теме