#python #string #dictionary #eval
Вопрос:
Итак, у меня есть несколько строк в столбце фрейма данных, которые выглядят, например, так:
{'Free to Play': 17555, 'Multiplayer': 10499, 'FPS': 9248, 'Action': 8188, 'Shooter': 7857, 'Class-Based': 6098, 'Team-Based': 5363, 'Funny': 5155, 'First-Person': 4846, 'Trading': 4512, 'Cartoony': 4240, 'Competitive': 4116, 'Online Co-Op': 4016, 'Co-op': 3920, 'Robots': 3112, 'Comedy': 3049, 'Tactical': 2726, 'Crafting': 2491, 'Cartoon': 2450, 'Moddable': 2315}
Я пытаюсь получить доступ к ключам dict, но, поскольку это все еще строка, я хотел преобразовать ее в словари и нашел людей, которые говорят, что для этого можно использовать eval. И да, когда я пытаюсь так, это работает нормально, и test_dict имеет тип dict:
test_str = "{'Early Access': 77, 'RPG': 202}"
test_dict = eval(test_str)
Тем не менее, при работе со строками в фрейме данных
tags = main_data["tags"]
for taglist in tags:
taglist = """ taglist """
tag_dict = eval(taglist)
tag_dict всегда остается строкой, и после некоторых строк eval выдает ошибки, подобные этим:
File "<string>", line 1
"{'Action': 2681, 'FPS': 2048, 'Multiplayer': 1659, 'Shooter': 1420, 'Classic': 1344, 'Team-Based': 943, 'First-Person': 799, 'Competitive': 790, 'Tactical': 734, "1990's": 564, 'e-sports': 550, 'PvP': 480, 'Military': 367, 'Strategy': 329, 'Score Attack': 200, 'Survival': 192, 'Old School': 164, 'Assassin': 151, '1980s': 144, 'Violent': 40}"
^
SyntaxError: invalid syntax
Я обнаружил, что это может быть проблемой с длиной строк, так как при использовании taglist = """"" taglist """""
eval не выдает никаких ошибок, проходит через все строки, но все равно они не преобразуются в dict и остаются str.
Может быть, я совершил какую-то ошибку новичка или есть лучшие подходы к решению моей проблемы?
Комментарии:
1. в сообщении отображается ошибка, строка недопустима. он содержит » … «1990-е годы»: 564 …`
2. Попробуйте удалить
"""
список тегов вокруг.3. Почему вы добавили двойные кавычки в строку? Если бы не синтаксическая ошибка,
eval()
ing просто выдал бы строку.4. Зачем ты это делаешь
""" taglist """
???5. Послушайте, лучший подход — не пытайтесь использовать такие строки . В первую очередь, почему они такие струны?
Ответ №1:
Поскольку вы сериализуете свой диктант на какое-то внешнее хранилище, я бы использовал json. Он предназначен для этого, в то время как эвал … хитер. И вы на самом деле запускаете код, поэтому, что бы кто-то ни поместил в базу данных, вы будете его запускать.
Есть одна загвоздка. Json ожидает двойные кавычки. Поскольку он уже записан в базу данных в виде кода python с одинарными кавычками вокруг ключей словаря, вам придется преобразовать их в двойные кавычки, чтобы они были законными json. Я бы предложил исправить это один раз в базе данных, а затем использовать json в дальнейшем.
import json
data_dict = {'Free to Play': 17555, 'Multiplayer': 10499, 'FPS': 9248, 'Action': 8188, 'Shooter': 7857, 'Class-Based': 6098, 'Team-Based': 5363, 'Funny': 5155, 'First-Person': 4846, 'Trading': 4512, 'Cartoony': 4240, 'Competitive': 4116, 'Online Co-Op': 4016, 'Co-op': 3920, 'Robots': 3112, 'Comedy': 3049, 'Tactical': 2726, 'Crafting': 2491, 'Cartoon': 2450, 'Moddable': 2315}
data_dict.update({'Early Access': 77, 'RPG': 202})
data_string = json.dumps(data_dict)
# write it to a file or database
# read it later, we'll assume that's data_string
data_dict = json.loads(data_string)
print (data_dict['RPG'])
database_string = "{'Free to Play': 17555, 'Multiplayer': 10499, 'FPS': 9248, 'Action': 8188, 'Shooter': 7857, 'Class-Based': 6098, 'Team-Based': 5363, 'Funny': 5155, 'First-Person': 4846, 'Trading': 4512, 'Cartoony': 4240, 'Competitive': 4116, 'Online Co-Op': 4016, 'Co-op': 3920, 'Robots': 3112, 'Comedy': 3049, 'Tactical': 2726, 'Crafting': 2491, 'Cartoon': 2450, 'Moddable': 2315}"
# this isn't a general purpose converter, but works for this case
# just to change the single quotes to double quotes
converted_to_legal_json = database_string.replace("'", '"')
data_dict = json.loads(converted_to_legal_json)
print (data_dict['Multiplayer'])
Я, вероятно, могу исправить вашу оценку, если вы хотите, но не могу сделать это прямо сейчас. Но, как я уже сказал, не рекомендуется. И я бы использовал ast.literal_eval вместо того, чтобы фактически выполнять его с помощью eval, по соображениям безопасности.