将Unicode字符串字典转换为Python字典

54

我有一段Unicode编码的字符串u"{'code1':1,'code2':1}",我想将其转换为字典格式。

我希望它呈现为{'code1':1,'code2':1} 格式。

我尝试使用unicodedata.normalize('NFKD', my_data).encode('ascii','ignore'),但它返回的是字符串而不是字典。

有人能帮忙吗?

5个回答

90
你可以使用内置的ast包:
import ast

d = ast.literal_eval("{'code1':1,'code2':1}")

在ast模块中的函数literal_eval的帮助信息:

literal_eval(node_or_string)

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


12
如果我有这样的内容{u'a': {u'nstext': u'(Article)', u'title': u'article title', u'namespace': u'0', u'len': u'4339', u'touched': u'20140829055924', u'id': u'28621'}, u'n': u'page'},这个答案会给我一个ValueError: malformed string。 - user3083324
1
每次我尝试时都遇到错误(像往常一样,对我来说什么都不起作用):SyntaxError: 解析时遇到意外的EOF,文件“<未知>”,第1行 700 000 ^ - Lawrence DeSouza
3
看起来您的文件有问题,而不是我的答案。不清楚您为什么要给它点个踩,但这取决于您。 - aga
3
我最终使用的代码如下:data_meta = json.loads(str(myjsonstring))。也许你的代码不是针对字符串而是针对文件的。 - Lawrence DeSouza
3
哇,我一直忙得不可开交地寻找像这样的东西! - DrStrangepork

16
您可以使用literal_eval。您可能还想确保创建的是字典,而不是其他东西。请使用自己的错误处理方法,而不是assert
from ast import literal_eval
from collections import MutableMapping

my_dict = literal_eval(my_str_dict)
assert isinstance(my_dict, MutableMapping)

12

编辑:事实证明我的假设是错误的;因为键没有用双引号包裹("),所以该字符串不是JSON。点击此处了解一些解决方法。

我猜你手头的可能是JSON,即JavaScript对象表示法。

你可以使用Python内置的json模块完成此操作:

import json
result = json.loads(u"{'code1':1,'code2':1}")   # will NOT work; see above

在我的情况下工作得很好。 - Ajay Kumar

2

当我从文件中读取json时,出现了Unicode错误。所以这个方法对我有效。

import ast
job1 = {}
with open('hostdata2.json') as f:
  job1= json.loads(f.read())

f.close()

#print type before converting this from unicode to dic would be <type 'unicode'>

print type(job1)
job1 =  ast.literal_eval(job1)
print "printing type after ast"
print type(job1)
# this should result <type 'dict'>

for each in job1:
 print each
print "printing keys"
print job1.keys()
print "printing values"
print job1.values()

当您在with语句中使用open()语句时,无需调用close()方法--一旦with结束,它会自动发生。 - JDM

0

您可以使用内置的eval函数将字符串转换为Python对象

>>> string_dict = u"{'code1':1, 'code2':1}"
>>> eval(string_dict)
{'code1': 1, 'code2': 1}

2
正如有人曾经告诉我一样,eval 是邪恶的。请使用 literal_eval 代替。 - pyrospade
@pyrospade 为什么这样? - Ishan mahajan
1
@Ishanmahajan,eval()对被执行的代码没有任何限制或保护。例如,它可以轻松使用os模块来重新组织文件夹、删除文件等。这是一个严重而危险的安全漏洞。另一方面,literal_eval非常严格受限。它只能在某些有限的表达式上运行,不会对应用程序本身以外的任何东西产生影响。 - JDM

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