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

2024-11-20 08:44:00
admin
原创
162
摘要:问题描述:如何将str字典的表示形式(例如以下字符串)转换为dict?s = "{'muffin' : 'lolz', 'foo' : 'kitty'}" 我不喜欢使用eval。我还可以使用什么?解决方案 1:您可以使用内置的ast.literal_eval:>>> im...

问题描述:

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

s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"

我不喜欢使用eval。我还可以使用什么?


解决方案 1:

您可以使用内置的ast.literal_eval

>>> import ast
>>> ast.literal_eval("{'muffin' : 'lolz', 'foo' : 'kitty'}")
{'muffin': 'lolz', 'foo': 'kitty'}

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

>>> 帮助(ast.literal_eval)
有关模块 ast 中函数 literal_eval 的帮助:

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

例如:

>>> 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

解决方案 2:

https://docs.python.org/library/json.html

JSON 可以解决这个问题,尽管它的解码器需要用双引号括住键和值。如果你不介意的话,可以使用替换 hack...

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 单引号的更多信息:jQuery.parseJSON 因 JSON 中的转义单引号而引发“无效 JSON”错误

解决方案 3:

使用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'>

解决方案 4:

以OP为例:

s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"

我们可以使用Yaml来处理这种字符串不标准的json:

>>> import yaml
>>> s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
>>> s
"{'muffin' : 'lolz', 'foo' : 'kitty'}"
>>> yaml.load(s)
{'muffin': 'lolz', 'foo': 'kitty'}

解决方案 5:

总结一下:

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

解决方案 6:

如果字符串始终可信,则可以使用eval(或literal_eval按建议使用;无论字符串是什么,它都是安全的。)否则,您需要一个解析器。如果 JSON 解析器(例如 simplejson)仅存储符合 JSON 方案的内容,它将起作用。

解决方案 7:

使用json。该ast库会消耗大量内存,而且速度较慢。我有一个需要读取 156Mb 文本文件的过程。Ast转换字典需要 5 分钟的延迟json,而使用内存则需要 1 分钟,减少了 60%!

解决方案 8:

string = "{'server1':'value','server2':'value'}"

#Now removing { and }
s = string.replace("{" ,"")
finalstring = s.replace("}" , "")

#Splitting the string based on , we get key value pairs
list = finalstring.split(",")

dictionary ={}
for i in list:
    #Get Key Value pairs separately to store in dictionary
    keyvalue = i.split(":")

    #Replacing the single quotes in the leading.
    m= keyvalue[0].strip('\'')
    m = m.replace("\"", "")
    dictionary[m] = keyvalue[1].strip('"\'')

print dictionary

解决方案 9:

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)

解决方案 10:

没有使用任何库(python2):

dict_format_string = "{'1':'one', '2' : 'two'}"
d = {}
elems  = filter(str.isalnum,dict_format_string.split("'"))
values = elems[1::2]
keys   = elems[0::2]
d.update(zip(keys,values))

注意:由于硬编码,因此split("'")仅适用于数据为“单引号”的字符串。

注意2:在python3中您需要包装filter()才能list()获取列表。

解决方案 11:

我无法使用上述任何答案,因为我有一个指定了 dtypes 的字符串,因此我使用了 json.load ,如下所示:

string_dict = """{'contexts': array(['Programmed cell death (PCD) is the regulated death of cells within an organism.', ..., '...'], dtype=object)},..."""

# Replace array( with np.array(
string_dict = string_dict.replace("array(", "np.array(")

# Evaluate the string as python code
python_dict = ast.literal_eval(string_dict)

解决方案 12:

ast.literal_eval如果您有一个无法通过或解析的 Python 对象的字符串表示json,请尝试使用asteval模块。您可以先通过 pip 安装它以使用它:pip install asteval

它比内置的ast或的主要优势在于,它可以比更轻松、更安全地eval评估复杂 Python 对象的字符串表示。特别是当你的字符串包含数学表达式(如、numpy 对象等)时使用它。ast`evalnanDecimal`

要使用它,我们必须实例化一个Interpreter对象并使用要评估的字符串来调用它。在下面的示例中,字典的字符串表示不是 JSON,并且包含无法通过转换的 NaN ast.literal_eval;但是,asteval.Interpreter它对其进行了正确的评估。

import ast
import json
from asteval import Interpreter

s = "{1: nan, 2: 3}"
ast.literal_eval(s)     # ValueError: malformed node or string
json.loads(s)           # JSONDecodeError
aeval = Interpreter()
aeval(s)                # {1: nan, 2: 3}

其他一些示例,literal_evaljson.loads失败但asteval有效。

  1. 如果您有 numpy 对象的字符串表示形式,并且系统上安装了 numpy,那么转换为正确的对象也会容易得多asteval

aeval = Interpreter()
aeval("{'a': array([ 1.,  2., nan])}")    # {'a': array([ 1.,  2., nan])}
  1. 默认情况下,asteval评估 numpy 函数;但是,如果您想让它以某种方式解析某些符号(例如 numpy dtypes),您可以定义自定义符号表并Interpreter在创建时将其传递给它。

下面是一个示例,其中创建了一个符号表,该表定义了如何评估 numpy dtypes、decimal.Decimal类型和null值,并将其传递给Interpreter

from asteval import Interpreter, make_symbol_table
from decimal import Decimal

s = "{'a': array(['text'], dtype=object), 'b': Decimal('3.33'), 'c': null, 'd': array([1, 2], dtype=int8)}"
symtable = make_symbol_table(object=object, Decimal=Decimal, null=None, int8='int8')
aeval = Interpreter(symtable=symtable)
d = aeval(s)
print(d)   # {'a': array(['text'], dtype=object), 'b': Decimal('3.33'), 'c': None, 'd': array([1, 2], dtype=int8)}

最后,请记住,由于它会评估任何 numpy/math 函数(实际上只要在symtable参数中定义,任何输入到其中的函数),请留意传递给它的输入。

解决方案 13:

我的字符串里面没有引号:

s = 'Date: 2022-11-29T10:57:01.024Z, Size: 910.11 KB'

我的解决方案是使用str.split

{k:v for k, v in map(lambda d: d.split(': '), s.split(', '))}

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用