string of kwargs to kwargs

Question:

I have a string like

s = "title='bah' name='john and jill' purple='haze' none=None i=1"

I am looking for a pythonic way of putting that into a dictionary (and a solution that does not choke on extra white spaces)?

Suggestions ?

Asked By: Nix

||

Answers:

>>> from ast import literal_eval
>>> s = "title='bah' name='john' purple='haze' none=None i=1"
>>> dict((k, literal_eval(v)) for k, v in (pair.split('=') for pair in s.split()))
{'purple': 'haze', 'i': 1, 'none': None, 'name': 'john', 'title': 'bah'}

(This won’t work if the inner strings contain whitespace, or if '=' appears as anything other than the key-value separator. Obviously the more complicated this gets the harder it is to parse, so…)

Answered By: Ismail Badawi
>>> dictionary = {}
>>> for i in s.split():
...     dictionary[i.split('=')[0]] = i.split('=')[1]
...
>>> dictionary
{'purple': "'haze'", 'i': '1', 'none': 'None', 'name': "'john'", 'title': "'bah'"}
Answered By: RanRag

If you have control over the strings, as you say you do, you could simply do this

>>> s = "title='bah' name='john' purple='haze' none=None i=1"
>>> eval("dict(%s)"%s.replace(" ",","))
{'i': 1, 'purple': 'haze', 'none': None, 'name': 'john', 'title': 'bah'}
>>> 
Answered By: John La Rooy

A combination of @gnibblers and @RanRag that does not barf on whitespace. (e.g. title=’foo bar’)

s = "title='bah' name='john' purple='haze' none=None i=1"
d = eval("dict(%s)"% ",".join(s.split()))
Answered By: Nix

Looks like @Nix missed the call to split() in previous answer.

Here is the corrected code:

>>> s = "title='bah' name='john' purple='haze' none=None i=1"
>>> d = eval("dict(%s)" % ','.join(s.split()))
>>> d
{'i': 1, 'purple': 'haze', 'none': None, 'name': 'john', 'title': 'bah'}
>>>

The original code:

s = "title='bah' name='john' purple='haze' none=None i=1"
d = eval("dict(%s)"% ",".join(s))

produces the following error:

>>> s = "title='bah' name='john' purple='haze' none=None i=1"
>>> d = eval("dict(%s)"% ",".join(s))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    dict(t,i,t,l,e,=,',b,a,h,', ,n,a,m,e,=,',j,o,h,n,', ,p,u,r,p,l,e,=,',h,a,z,e,', ,n,o,n,e,=,N,o,n,e, ,i,=,1)
                   ^
SyntaxError: invalid syntax
Answered By: John Shue
from operator import methodcaller
from ast import literal_eval
kv_split = methodcaller('split', '=', 1)
{k: literal_eval(v) for k, v in map(kv_split, s.split(" "))}
# {'purple': 'haze', 'i': 1, 'none': None, 'name': 'john', 'title': 'bah'}
Answered By: eroot163pi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.