2

Say there is a file with multiple lines of dictionaries,

{"apple": "red", "oarange": "orange", "pear": "green"}

From this a string is captured, for

>>> input = '"apple": "red", "oarange": "orange", "pear": "green"'
>>> input
'"apple": "red", "oarange": "orange", "pear": "green"'

and, of course, I could easily capture it as

>>> input = '{"apple": "red", "oarange": "orange", "pear": "green"}'
>>> input
'{"apple": "red", "oarange": "orange", "pear": "green"}'

regardless, I wish to take input and make it a new value of a new dictionary, so, using two different methods that don't work,

>>> mydict['plate1'] = input
>>> mydict['plate2'] = {input}

yields the undesirable

>>> mydict
{'test': set(['"user_name": "BO01", "password": "password", "attend_password": "BO001"']), 'plate1': '"apple": "red", "oarange": "orange", "pear": "green"'}

neither of which is the desired

'plate1' : {"apple": "red", "oarange": "orange", "pear": "green"}

anyone know how to take the input string and make it play nicely as a dictionary value for the parent dictionary?

Shawn Mehan
  • 4,513
  • 9
  • 31
  • 51

2 Answers2

3

You could try use split and strip but the simplest way i to wrap the string in brackets and call ast.literal_eval:

from ast import literal_eval

inp = '"apple": "red", "oarange": "orange", "pear": "green"'


d = literal_eval("{{{}}}".format(inp))

Output:

{'pear': 'green', 'oarange': 'orange', 'apple': 'red'}

You almost have a dict with '"apple": "red", "oarange": "orange", "pear": "green"', the only this that us missing is the brackets so using "{{{}}}" with str.format wraps the string in brackets allowing us to call literal_eval.

On a side note if you have dicts in a file and that is actually where the strings are coming from you should either json.loads or literal_eval each line directly.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • Tapadh leat. Now, I've just gone and looked at the pydoc for `literal_eval`, and I don't understand the working of the `"{{{}}}"`. Will you please explain that in the answer a wee bit as well? – Shawn Mehan Oct 20 '15 at 23:05
  • I would take your advice and load directly from the file, but there is of course other rubbish in each line that needs to be broken out. – Shawn Mehan Oct 20 '15 at 23:09
  • 1
    I added a bit more explanation, when you use `{}` in the string itself they must be escaped so you need up with `"{{{}}}"`, the inner is what you are passing to format the outer brackets are just escaping the other. If you have rubbish in the file and only want the valid lines that are dicts you could just use a try/expect to catch the bad lines – Padraic Cunningham Oct 20 '15 at 23:12
2

You can use the fact that using split('"') gives you the keys and values of your dictionary in strategic places. Using that, a possible solution would be:

input = '{"apple": "red", "oarange": "orange", "pear": "green"}' # Your input
words = input.split('"')
fruits = words[1::4]  # Location of keys
colors = words[3::4]  # Location of values

d = dict(zip(fruits, colors)) # Create the dictionary
d = {'plate1': d} # Make that dictionary a value of the key 'plate1'

d is then:

{'plate1': {'pear': 'green', 'oarange': 'orange', 'apple': 'red'}}
dorverbin
  • 467
  • 1
  • 4
  • 17