包含列表和其他数据类型的字符串到字典,而不更改python中的数据类型

包含列表和其他数据类型的字符串到字典,而不更改python中的数据类型,python,Python,我有一个字符串,如下所示: key_val = "count=2, name=['hello', 'hi'], word='Dial::100', roll=12" d_key_val = {'count'=2, 'name'=['hello', 'hi'], 'word'='Dial::100', 'roll'=12} 我需要从字符串中获取字典,如下所示: key_val = "count=2, name=['hello', 'hi'], word='Dial::100', roll=12

我有一个字符串,如下所示:

key_val = "count=2, name=['hello', 'hi'], word='Dial::100', roll=12"
d_key_val = {'count'=2, 'name'=['hello', 'hi'], 'word'='Dial::100', 'roll'=12}
我需要从字符串中获取字典,如下所示:

key_val = "count=2, name=['hello', 'hi'], word='Dial::100', roll=12"
d_key_val = {'count'=2, 'name'=['hello', 'hi'], 'word'='Dial::100', 'roll'=12}
我尝试了以下方法:

regx = r'(?P<key>\w+)=(?P<value>\[.+?\]|\d+|\S+)'
r_key_val = re_findall(regx, key_val)
for key, value in r_key_val:
        d_key_val[key] = value

是否有任何方法或正则表达式可以将值存储为与字符串中相同的数据类型?

regex
不能这样做,但您可以!您可以编写如下函数,将
正则表达式
写出并转换为适当的类型

def type_converter(v):
    if v[0] == '[' and v[-1] == ']':
        v = v.replace('[', '').replace(']', '')
        return [type_converter(x) for x in v.split(',')]
    try:
        v = int(v)
    except ValueError:
        try:
            v = float(v)
        except ValueError:
            pass
    finally:
        return v
要将其添加到代码中,只需执行以下操作:

regx = r'(?P<key>\w+)=(?P<value>\[.+?\]|\d+|\S+)'
r_key_val = re_findall(regx, key_val)
for key, value in r_key_val:
    d_key_val[key] = type_converter(value)  # <- this
regx=r'(?P\w+)=(?P\[.+?\]\d+\S+)
r_key_val=r_findall(regx,key_val)
对于键,r_key_val中的值:

d_key_val[key]=类型_转换器(值)#如果您100%确定数据是“安全的”,您可以将其作为参数:

如果您不确定,最好不要使用
eval


或者,您可以使用正则表达式并使用来计算

>>> regx = r'(?P<key>\w+)=(?P<value>\[.+?\]|\d+|\S+)'
>>> {k: ast.literal_eval(v) for k, v in re.findall(regx, key_val)}
{'count': 2, 'name': ['hello', 'hi'], 'roll': 12, 'word': ('Dial::100',)}
>>regx=r'(?P\w+)=(?P\[.+?\]\124;\ d+\S+)
>>>{k:ast.literal_eval(v)for k,v in re.findall(regx,key_val)}
{'count':2,'name':['hello','hi'],'roll':12,'word':('Dial::100',)}

(注意:我没有详细检查您的正则表达式。)您也可以尝试将
ast.literal_eval
应用于整个表达式,而不是不太安全的
eval
,但这需要一些预处理,例如将
=
替换为
并在键上添加引号,这可能不适用于包含这些符号的字符串值。

但是对于
列表
部分来说更难。也许可以使用
ast.literal\u eval
来代替?@tobias\u k我后来注意到了这一点,但我将函数更新为递归函数来处理这个问题。在一天结束时,
ast.literal\u eval
或一些花哨的
json
命令可能会更方便。相关:
>>> regx = r'(?P<key>\w+)=(?P<value>\[.+?\]|\d+|\S+)'
>>> {k: ast.literal_eval(v) for k, v in re.findall(regx, key_val)}
{'count': 2, 'name': ['hello', 'hi'], 'roll': 12, 'word': ('Dial::100',)}