Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将字典的字符串表示形式转换为字典?_Python_String_Dictionary - Fatal编程技术网

Python 将字典的字符串表示形式转换为字典?

Python 将字典的字符串表示形式转换为字典?,python,string,dictionary,Python,String,Dictionary,如何将dict的str表示形式(如以下字符串)转换为dict s = "{'muffin' : 'lolz', 'foo' : 'kitty'}" 我不喜欢使用eval。我还能用什么 主要原因是,我的一个同事编写了一个类,将所有输入转换为字符串。我没有心情去修改他的类来处理这个问题。如果字符串总是可以信任的,你可以使用eval(或者按照建议使用literal\u eval;不管字符串是什么都是安全的)。否则你需要一个解析器。如果JSON解析器(例如simplejson)只存储符合JSON方案的

如何将
dict
str
表示形式(如以下字符串)转换为
dict

s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
我不喜欢使用
eval
。我还能用什么

主要原因是,我的一个同事编写了一个类,将所有输入转换为字符串。我没有心情去修改他的类来处理这个问题。

如果字符串总是可以信任的,你可以使用
eval
(或者按照建议使用
literal\u eval
;不管字符串是什么都是安全的)。否则你需要一个解析器。如果JSON解析器(例如simplejson)只存储符合JSON方案的内容,那么它就可以工作。

您可以使用内置的:

这比使用
eval
更安全。正如它自己的文件所说:

>>> help(ast.literal_eval) Help on function literal_eval in module ast: literal_eval(node_or_string) Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None. >>>帮助(ast.literal\u eval) 有关模块ast中函数文字评估的帮助: 文字值(节点或字符串) 安全地计算表达式节点或包含Python的字符串 表情。提供的字符串或节点只能由以下内容组成 Python文字结构:字符串、数字、元组、列表、dicts、boolean、, 没有。 例如:

>>> eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
  File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 208, in rmtree
    onerror(os.listdir, path, sys.exc_info())
  File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 206, in rmtree
    names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mongo'
>>> ast.literal_eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval
    return _convert(node_or_string)
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert
    raise ValueError('malformed string')
ValueError: malformed string
评估(“shutil.rmtree('mongo')) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“”,第1行,在 rmtree中的文件“/opt/Python-2.6.1/lib/python2.6/shutil.py”,第208行 onerror(os.listdir,path,sys.exc_info()) 文件“/opt/Python-2.6.1/lib/python2.6/shutil.py”,第206行,在rmtree中 name=os.listdir(路径) OSError:[Errno 2]没有这样的文件或目录:“mongo” >>>ast.literal_eval(“shutil.rmtree('mongo')) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/opt/Python-2.6.1/lib/python2.6/ast.py”,第68行,文本形式 返回\u转换(节点\u或字符串) 文件“/opt/Python-2.6.1/lib/python2.6/ast.py”,第67行,in\u convert raise VALUERROR('格式错误的字符串') ValueError:格式不正确的字符串

JSON可以解决这个问题,尽管它的解码器需要在键和值之间加上双引号。如果你不介意替换黑客

import json
s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
json_acceptable_string = s.replace("'", "\"")
d = json.loads(json_acceptable_string)
# d = {u'muffin': u'lolz', u'foo': u'kitty'}
请注意,如果键或值中包含单引号,则由于字符替换不当,此操作将失败。仅当您强烈反对eval解决方案时,才建议使用此解决方案


关于json单引号的更多信息:

使用
json.loads

>>> import json
>>> h = '{"foo":"bar", "foo2":"bar2"}'
>>> d = json.loads(h)
>>> d
{u'foo': u'bar', u'foo2': u'bar2'}
>>> type(d)
<type 'dict'>
导入json >>>h='{“foo”:“bar”,“foo2”:“bar2”}' >>>d=json.loads(h) >>>d {u'foo':u'bar',u'foo2':u'bar2'} >>>类型(d)
使用
json
ast
库消耗大量内存,速度较慢。我有一个进程需要读取156Mb的文本文件
Ast
转换字典
json
延迟5分钟,节省60%的内存1分钟

以OP为例:

s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
我们可以使用来处理这种字符串形式的非标准json:

>>> import yaml
>>> s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
>>> s
"{'muffin' : 'lolz', 'foo' : 'kitty'}"
>>> yaml.load(s)
{'muffin': 'lolz', 'foo': 'kitty'}
未使用任何LIB(python2):

注意:由于它已硬编码
split(“”)
仅适用于数据为“单引号”的字符串

注2:在python3中,您需要将
filter()
包装到
list()
以获取列表。

要总结:

import ast, yaml, json, timeit

descs=['short string','long string']
strings=['{"809001":2,"848545":2,"565828":1}','{"2979":1,"30581":1,"7296":1,"127256":1,"18803":2,"41619":1,"41312":1,"16837":1,"7253":1,"70075":1,"3453":1,"4126":1,"23599":1,"11465":3,"19172":1,"4019":1,"4775":1,"64225":1,"3235":2,"15593":1,"7528":1,"176840":1,"40022":1,"152854":1,"9878":1,"16156":1,"6512":1,"4138":1,"11090":1,"12259":1,"4934":1,"65581":1,"9747":2,"18290":1,"107981":1,"459762":1,"23177":1,"23246":1,"3591":1,"3671":1,"5767":1,"3930":1,"89507":2,"19293":1,"92797":1,"32444":2,"70089":1,"46549":1,"30988":1,"4613":1,"14042":1,"26298":1,"222972":1,"2982":1,"3932":1,"11134":1,"3084":1,"6516":1,"486617":1,"14475":2,"2127":1,"51359":1,"2662":1,"4121":1,"53848":2,"552967":1,"204081":1,"5675":2,"32433":1,"92448":1}']
funcs=[json.loads,eval,ast.literal_eval,yaml.load]

for  desc,string in zip(descs,strings):
    print('***',desc,'***')
    print('')
    for  func in funcs:
        print(func.__module__+' '+func.__name__+':')
        %timeit func(string)        
    print('')
结果:

*** short string ***

json loads:
4.47 µs ± 33.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
builtins eval:
24.1 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
ast literal_eval:
30.4 µs ± 299 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
yaml load:
504 µs ± 1.29 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

*** long string ***

json loads:
29.6 µs ± 230 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
builtins eval:
219 µs ± 3.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ast literal_eval:
331 µs ± 1.89 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
yaml load:
9.02 ms ± 92.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
结论:
更喜欢json.loads

Siva Kameswara Rao Munipalle的优化代码

s = s.replace("{", "").replace("}", "").split(",")
            
dictionary = {}

for i in s:
    dictionary[i.split(":")[0].strip('\'').replace("\"", "")] = i.split(":")[1].strip('"\'')
            
print(dictionary)


从2.6开始,simplejson作为json模块包含在Python标准库中。是的,这是一个很好的答案,但请注意,官方json不支持单引号字符串,如原始海报示例中所示。我应该补充一点,您需要清理字符串以用于ast.literal\u eval。(确保字符串中的引号/双引号被转义)我在Python2.6(x86)上的windows 7 x64文件“D:\Python26\lib\ast.py”,第48行,在literal\u eval node\u或\u string=parse(node\u或\u string,mode='eval')文件“D:\Python26\lib\ast.py”,第36行,在parse return compile(expr,filename,mode,仅PyCF\u ast)中遇到此错误文件“”,第1行^SyntaxError:无效的语法关于
“dict(a=1)”
样式字符串如何?这似乎不适用于字典中的枚举值。例如:d=“{'col':,'val':2}”为什么不使用json.dumps和json.loads insead,我发现这个解决方案比使用evalI更高级。我不认为它回答了OP的答案。我们如何使用json.laads将字符串s=“{'muffin':'lolz','foo':'kitty'}”转换为dict?@technazic:json.loads(h.replace(“,”,“,”))但是,有一些限制,例如:h='{“muffin”:“lolz”,“foo”:“kitty”,}',h='{“muffin's”:“lolz”,“foo”:“kitty”},(刚刚注意到类似答案中的部分相同注释…为了完整性,仍保留在这里…)在我看来,这是最短、最简单的方法…绝对是我个人喜欢的方法。@nostradamus有太多异常、浮点值、元组等,但有其局限性:尝试转换字符串“{foo':'bar',}”“我正在寻找此解决方案。
+1
用于通知解码器需要在键和值周围使用双引号。另一个问题是,
”{0:'Hello'}“
。如果您有尾随逗号(不符合JSON),这也会失败,例如:“{muffin':'lolz',foo':'kitty',}”单引号字符串、元组文字和尾随逗号不是有效的JSON。
JSON.loads
将仅对有效的JSON字符串有效。请参阅此处的规范:使用
JSON.loads
是最安全的解决方案,因此尽可能使用。我建议在必要时将输入转换为有效的JSON。如果你有unicode字符串这将导致'yes'和'no'字符串转换为True/false我得到的值工作正常…但我得到了一个错误“AMLLoadWarning:调用yaml.load()而不使用Loader=…是不推荐的,因为默认的Loader是不安全的。请阅读完整的详细信息。”什么
import ast, yaml, json, timeit

descs=['short string','long string']
strings=['{"809001":2,"848545":2,"565828":1}','{"2979":1,"30581":1,"7296":1,"127256":1,"18803":2,"41619":1,"41312":1,"16837":1,"7253":1,"70075":1,"3453":1,"4126":1,"23599":1,"11465":3,"19172":1,"4019":1,"4775":1,"64225":1,"3235":2,"15593":1,"7528":1,"176840":1,"40022":1,"152854":1,"9878":1,"16156":1,"6512":1,"4138":1,"11090":1,"12259":1,"4934":1,"65581":1,"9747":2,"18290":1,"107981":1,"459762":1,"23177":1,"23246":1,"3591":1,"3671":1,"5767":1,"3930":1,"89507":2,"19293":1,"92797":1,"32444":2,"70089":1,"46549":1,"30988":1,"4613":1,"14042":1,"26298":1,"222972":1,"2982":1,"3932":1,"11134":1,"3084":1,"6516":1,"486617":1,"14475":2,"2127":1,"51359":1,"2662":1,"4121":1,"53848":2,"552967":1,"204081":1,"5675":2,"32433":1,"92448":1}']
funcs=[json.loads,eval,ast.literal_eval,yaml.load]

for  desc,string in zip(descs,strings):
    print('***',desc,'***')
    print('')
    for  func in funcs:
        print(func.__module__+' '+func.__name__+':')
        %timeit func(string)        
    print('')
*** short string ***

json loads:
4.47 µs ± 33.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
builtins eval:
24.1 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
ast literal_eval:
30.4 µs ± 299 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
yaml load:
504 µs ± 1.29 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

*** long string ***

json loads:
29.6 µs ± 230 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
builtins eval:
219 µs ± 3.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ast literal_eval:
331 µs ± 1.89 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
yaml load:
9.02 ms ± 92.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
s = s.replace("{", "").replace("}", "").split(",")
            
dictionary = {}

for i in s:
    dictionary[i.split(":")[0].strip('\'').replace("\"", "")] = i.split(":")[1].strip('"\'')
            
print(dictionary)