Reputation: 976
The format of string is like "a:1 b:2 c:x d:2.13e-5"
, is there some way to convert it to python dict quickly and simply?
-------------- edit line --------------
According the great answers, I tried several methods (in ipython):
In [6]: import re
In [7]: %paste
def f1(line):
item_dict = {}
for item in line.split():
kv = item.split(':')
item_dict[kv[0]] = kv[1]
def f2(line):
item_dict = {}
item_pat = re.compile(r'(\w+):(.+)')
for item in line.split():
m_res = item_pat.match(item)
item_dict[m_res.group(1)] = m_res.group(2)
def f3(line):
dict(item.split(':') for item in line.split())
## -- End pasted text --
In [8]: line = 'a:1 b:3243 dsfds:4323llsjdf \t fdsf:3232l'
In [9]: %timeit f1(line)
100000 loops, best of 3: 3.99 us per loop
In [10]: %timeit f2(line)
100000 loops, best of 3: 8.83 us per loop
In [11]: %timeit f3(line)
100000 loops, best of 3: 5.19 us per loop
The first method f1()
seems faster, but in my application, it still use much time(about 30% of all) because it's invoked millions of times.
Are there any more effective ways? Or cython
?
Upvotes: 1
Views: 199
Reputation: 137398
>>> s = "a:1 b:2 c:x d:2.13e-5"
>>> dict( p.split(':') for p in s.split(' ') )
{'a': '1', 'c': 'x', 'b': '2', 'd': '2.13e-5'}
This split
s the string, first by spaces, to get the key-value pairs (p
). Then it splits each pair by ':' to yield each key/value to be added to the dictionary.
Note that no conversion has taken place. All keys/values are still strings. To do any better than this, you're going to need a somewhat smart function that will convert any input string into your expected types.
Upvotes: 8
Reputation: 133534
import ast
def guess(s):
try:
return ast.literal_eval(s)
except ValueError:
return s
s = "a:1 b:2 c:x d:2.13e-5"
print dict(map(guess, x.split(':')) for x in s.split())
{'a': 1, 'c': 'x', 'b': 2, 'd': 2.13e-05}
Upvotes: 6