将字符串转换为字典

3

我知道这似乎是一个愚蠢的问题,但无论如何。

我正在尝试将字典的字符串表示转换回字典。

我的工作流程如下:

d = {1:2}
s = str(d)

当我执行以下操作时:

dict(s)

我得到了以下错误信息:

ValueError: 字典更新序列的第0个元素长度为1,需要2个

当我执行以下操作时:

json.loads(s)

我得到了这个错误信息:
ValueError: Expecting property name: line 1 column 1 (char 1)
如何将它转换回一个字典?
更新:
我应该提到,实际数据如下:
{'cell_num': u'', 'home_num': u'16047207276', 'registration_country': u'US', 'registration_ip': u'71.102.221.29', 'last_updated': datetime.datetime(2010, 9, 27, 15, 41, 59), 'address': {'country': u'US', 'state': u'CA', 'zip': u'', 'city': u'Santa Barbara', 'street': u'', 'confirmed': False, 'created': datetime.datetime(2010, 6, 24, 10, 23), 'updated': datetime.datetime(2010, 6, 24, 10, 23)}, 'old_home_num': u'16047207276', 'old_cell_num': u''}
在这种情况下,使用json.loads和ast.literal_eval()不合适。所以我进一步尝试使用标准的Python pickle库对其进行反序列化。
import pickle pickle.loads(data)
但是我得到了以下错误:
KeyError: '{'

2
你永远不会直接调用 obj.__str__() - 而是使用 str(obj)。但无论如何,这也不是你想要的 :) - ThiefMaster
请使用json模块代替... - Wooble
3个回答

10

如果您需要一个便携式的字符串表示,可以使用 s = json.dumps(d),然后可以使用 json.loads(s)重新加载。

但是,这仅适用于JSON兼容类型。如果您只想在Python中使用它,则最强大的选项是pickle(注意:永远不要反序列化不可信数据!)。

要创建一个可由 pickle.loads() 加载的字符串,您需要使用 pickle.dumps() 从原始对象创建它(即像使用 json 一样,但使用 pickle)。

但是,如果您已经拥有了那个字符串,您可以使用eval(s)将其作为Python表达式进行求值。虽然使用repr只对实际具有有效Python代码的repr的对象有效,但这通常是一个坏主意。


实际数据如下:{'cell_num': u'', 'home_num': u'16047207276', 'registration_country': u'US', 'registration_ip': u'71.102.221.29', 'last_updated': datetime.datetime(2010, 9, 27, 15, 41, 59), 'address': {'country': u'US', 'state': u'CA', 'zip': u'', 'city': u'Santa Barbara', 'street': u'', 'confirmed': False, 'created': datetime.datetime(2010, 6, 24, 10, 23), 'updated': datetime.datetime(2010, 6, 24, 10, 23)}, 'old_home_num': u'16047207276', 'old_cell_num': u''} - Pol
好的,由于日期时间的原因,它不兼容JSON。Pickle是最简单的解决方案。 - ThiefMaster
它是Unicode编码。而且json.loads()也会返回Unicode编码。 - Pol

7
尝试使用ast.literal_eval(),它是最安全的方法。
import ast
ast.literal_eval('{1:2}')
=> '{1:2}'

来自链接文档:

安全地评估表达式节点或包含Python表达式的字符串。提供的字符串或节点只能由以下Python字面结构组成:字符串、数字、元组、列表、字典、布尔值和None。

这可用于安全地评估来自不受信任来源的包含Python表达式的字符串,而无需自行解析值。


实际数据如下:{'cell_num': u'', 'home_num': u'16047207276', 'registration_country': u'US', 'registration_ip': u'71.102.221.29', 'last_updated': datetime.datetime(2010, 9, 27, 15, 41, 59), 'address': {'country': u'US', 'state': u'CA', 'zip': u'', 'city': u'Santa Barbara', 'street': u'', 'confirmed': False, 'created': datetime.datetime(2010, 6, 24, 10, 23), 'updated': datetime.datetime(2010, 6, 24, 10, 23)}, 'old_home_num': u'16047207276', 'old_cell_num': u''} - Pol
在您的情况下,我遇到了不同的错误: ValueError:字符串格式错误 - Pol
我认为这是一个非常好的解决方案。 - Kyokook Hwang
@Pol 这是因为 datetime 对象,literal_eval() 似乎无法解析它们。如果字典由简单的数据类型组成,我的解决方案将更可取。但不幸的是,它对你的实际数据不起作用 :( - Óscar López
@Pol 或许你应该把那些数据放在问题本身,因为这似乎与给出正确答案有关。 - SethMMorton

1

试试这个:

import pickle

pickle.loads(data)

这个东西曾经在过去帮了我一次忙。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接