I have malformed string:
a = '(a,1.0),(b,6.0),(c,10.0)'
I need dict
:
d = {'a':1.0, 'b':6.0, 'c':10.0}
I try:
print (ast.literal_eval(a))
#ValueError: malformed node or string: <_ast.Name object at 0x000000000F67E828>
Then I try replace chars to 'string dict'
, it is ugly and does not work:
b = a.replace(',(','|{').replace(',',' : ')
.replace('|',', ').replace('(','{').replace(')','}')
print (b)
{a : 1.0}, {b : 6.0}, {c : 10.0}
print (ast.literal_eval(b))
#ValueError: malformed node or string: <_ast.Name object at 0x000000000C2EA588>
What do you do? Something missing? Is possible use regex
?
If there are always 2 comma-separated values inside parentheses and the second is of a float type, you may use
See the Python demo and the (quite generic) regex demo. This pattern just matches a
(
, then 0+ chars other than a comma and)
capturing into Group 1, then a comma is matched, then any 0+ chars other than)
(captured into Group 2) and a)
.As the pattern above is suitable when you have pre-validated data, the regex can be restricted for your current data as
See the regex demo
Details:
\(
- a literal(
(\w+)
- Capturing group 1: one or more word (letter/digit/_
) chars,
- a comma(\d*\.?\d+)
- a common integer/float regex: zero or more digits, an optional.
(decimal separator) and 1+ digits\)
- a literal closing parenthesis.the reason why
eval()
dose not work is thea, b, c
are not defined, we can define those with it's string form and eval will get that string form to useto do this in regex way:
No need for regexes, if your string is in this format.
We remove the first opening parantheses and last closing parantheses to get the key-value pairs by splitting on
),(
. The pairs can then be split on the comma.To cast to float, the list comprehension gets a little longer:
Given the string has the above stated format, you could use regex substitution with backrefs:
So you look for a pattern
(x,
(withx
a sequence of\w
s and you substitute it into('x',
. The result is then:and then parse
a_fix
and convert it to adict
:The result in then: