Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.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 将字符串元组转换为dict_Python_Regex_String_Dictionary_Replace - Fatal编程技术网

Python 将字符串元组转换为dict

Python 将字符串元组转换为dict,python,regex,string,dictionary,replace,Python,Regex,String,Dictionary,Replace,我的字符串格式不正确: a = '(a,1.0),(b,6.0),(c,10.0)' 我需要听写: d = {'a':1.0, 'b':6.0, 'c':10.0} result = dict(ast.literal_eval(a_fix)) 我尝试: print (ast.literal_eval(a)) #ValueError: malformed node or string: <_ast.Name object at 0x000000000F67E828> 你是做什么

我的字符串格式不正确:

a = '(a,1.0),(b,6.0),(c,10.0)'
我需要听写:

d = {'a':1.0, 'b':6.0, 'c':10.0}
result = dict(ast.literal_eval(a_fix))
我尝试:

print (ast.literal_eval(a))
#ValueError: malformed node or string: <_ast.Name object at 0x000000000F67E828>

你是做什么的?少了什么?是否可以使用
regex

如果括号内始终有两个逗号分隔的值,而第二个值是浮点型的,则可以使用

import re
s = '(a,1.0),(b,6.0),(c,10.0)'
print(dict(map(lambda (w, m): (w, float(m)), [(x, y) for x, y in re.findall(r'\(([^),]+),([^)]*)\)', s) ])))
请参阅和(相当通用)。此模式只匹配一个
,然后是除逗号和
之外的0+字符)
捕获到组1,然后是一个逗号,然后是除
(捕获到组2)和
)之外的任何0+字符

由于上面的模式适用于预验证数据,因此可以根据需要对当前数据限制正则表达式

r'\((\w+),(\d*\.?\d+)\)'

详细信息

  • \(
    -文字
  • (\w+)
    -捕获组1:一个或多个单词(字母/数字/
    )\uu
    )字符
  • -逗号
  • (\d*\?\d+)
    -通用整数/浮点正则表达式:零或多个数字,可选的
    (十进制分隔符)和1+个数字
  • \)
    -一个文字右括号

如果字符串具有上述格式,则可以使用带backref的正则表达式替换:

因此,您查找一个模式
(x,
(带有
x
一系列
\w
s),然后将其替换为
('x',
)。结果如下:

# result
a_fix == "('a',1.0),('b',6.0),('c',10.0)"
然后解析
a_fix
并将其转换为
dict

d = {'a':1.0, 'b':6.0, 'c':10.0}
result = dict(ast.literal_eval(a_fix))
结果是:

>>> dict(ast.literal_eval(a_fix))
{'b': 6.0, 'c': 10.0, 'a': 1.0}

如果字符串是这种格式,则不需要正则表达式

>>> a = '(a,1.0),(b,6.0),(c,10.0)'
>>> d = dict([x.split(',') for x in a[1:-1].split('),(')])
>>> print(d)
{'c': '10.0', 'a': '1.0', 'b': '6.0'}
我们删除第一个打开的旁命题和最后一个关闭的旁命题,通过在
),(
)上拆分得到键值对。然后可以在逗号上拆分这些对

要强制转换为浮动,列表理解会稍微长一些:

d = dict([(a, float(b)) for (a, b) in [x.split(',') for x in a[1:-1].split('),(')]])
eval()
不起作用的原因是
a、b、c
没有定义,我们可以用它的字符串形式定义它们,eval将使用该字符串形式

In [11]: text = '(a,1.0),(b,6.0),(c,10.0)'

In [12]: a, b, c = 'a', 'b', 'c'

In [13]: eval(text)
Out[13]: (('a', 1.0), ('b', 6.0), ('c', 10.0))

In [14]: dict(eval(text))
Out[14]: {'a': 1.0, 'b': 6.0, 'c': 10.0}
要以正则表达式的方式执行此操作,请执行以下操作:

In [21]: re.sub(r'\((.+?),', r'("\1",', text)
Out[21]: '("a",1.0),("b",6.0),("c",10.0)'
In [22]: eval(_)
Out[22]: (('a', 1.0), ('b', 6.0), ('c', 10.0))

In [23]: dict(_)
Out[23]: {'a': 1.0, 'b': 6.0, 'c': 10.0}

因为每个元组的第一个元素不是char,而是一个
a
(因此是一个标识符),所以字符串是mall形式的。是的,这是我认为的主要问题。给定的字符串是否始终具有上述格式?确实可以使用正则表达式修复字符串,但如果输入格式未指定,则正则表达式替换有点危险。我认为,我希望是。您可以(事实上,我认为您应该)避免使用regexes@BlackBear:如果需要验证,那么正则表达式将是一个优势,我现在添加详细信息。首先,
eval
被认为是非常危险的(因为黑客可能引入任意代码,请注意OP使用的是
literal\u eval
,这是另一种情况)。接下来,OP通常不知道键是什么,最后,在这里您为变量分配了很多值(您可能希望用于其他内容)…当然,在我的答案中添加了它。嵌套列表理解ftw!感谢您的回答。不幸的是,我无法在pandas中实现,因此我接受另一个答案。