Is eval () better than introspection?

Here is my situation, I have a line as follows

'a':1 'b':2 'c':3 

I want to turn this into a dict, so I have two options:

  • Divide the string by ' ' and then by ':' , then put the pairs in a dict .

  • Replace ' ' with ',' , add '{' and '}' to the string and use eval() to get the dict .

So my question is: which one is faster?

+4
source share
3 answers

I would do it like this:

 import ast result = ast.literal_eval(''.join(["{", s.replace(" ", ", "), "}"])) 

You can also do this (although the difference may be slight):

 import ast result = ast.literal_eval("{" + s.replace(" ", ", ") + "}") 

It is better to use ast.literal_eval as safer for this purpose than to use eval() .

+10
source

Ok, here they are all still:

 import ast, re, json s = "'a':1 'b':2 'c':3" def a_eval(s): s = s.replace(' ', ',') return eval('{%s}' % s) def a_ast(s): s = s.replace(' ', ',') return ast.literal_eval('{%s}' % s) def a_parse(s): d = {} for p in s.split(): k, v = p.split(':') d[k.strip("'")] = int(v) return d def a_re(s): d = [] re.sub(r"'(\w+)':(\w+)", lambda m: d.append(m.groups()), s) return dict((a, int(b)) for a, b in d) def a_json(s): s = s.replace(' ', ',') s = s.replace("'", '"') return json.loads('{%s}' % s) #eof import timeit setup = open(__file__).read().split('#eof')[0] results = [] for p in dir(): if p.startswith('a_'): results.append((timeit.timeit('%s(s)' % p, setup, number=10000), p)) for p in sorted(results): print '%.4f %s' % p 

Results:

 0.0753 a_parse 0.1068 a_json 0.1455 a_re 0.2211 a_eval 0.3297 a_ast 

And on longer lines, json winner:

 long_s = ((s + ' ') * 100).strip() for p in dir(): if p.startswith('a_'): results.append((timeit.timeit('%s("%s")' % (p, long_s), setup, number=100), p)) for p in sorted(results): print '%.4f %s' % p 

Results:

 0.0166 a_json 0.0528 a_parse 0.0565 a_re 0.0927 a_eval 0.1519 a_ast 
+6
source

json.loads faster than ast.literal_eval :

 $ python -m timeit -s "s = '\'a\':1 \'b\':2';s = '{' + s.replace(' ', ', ') + ' }'; import json" "json.loads(s.replace('\'', '\"'))" 100000 loops, best of 3: 5.11 usec per loop $ python -m timeit -s "s = '\'a\':1 \'b\':2';s = '{' + s.replace(' ', ', ') + ' }'; import ast" "ast.literal_eval(s)" 100000 loops, best of 3: 19.4 usec per loop 
+2
source

All Articles