0

Hello all and sorry if the title was worded poorly. I'm having a bit of trouble wrapping my head around how to solve this issue I have encountered. I would have liked to simply pass a dict as the value for this key in my json obj but sadly I have to pass it as a string. So, I have a json dict object that looks like this

data = {"test": "Fuzz", "options": "'{'size':'Regular','connection':'unconnected'}'"}. Obviously, I would prefer that the second dict value weren't a string representation of a dictionary but rather a dictionary. Is the best route here to just strip the second and second to last single quotes for the data[options] or is there a better alternative?

Sorry for any confusion. This is how the json object looks after I perform

json.dump(data, <filename>)

The value for options can be thought of as another variable say x and it's equivalent to '{'size':'Regular','connection':'unconnected'}'

I could do x[1:-1] but I'm not sure if that is the most pythonic way to do things here.

UCProgrammer
  • 517
  • 7
  • 21
  • Could you show bits of code on how u get the data – Adelina Aug 06 '18 at 11:52
  • 2
    You can try using [ast.literal_eval](https://stackoverflow.com/questions/988228/convert-a-string-representation-of-a-dictionary-to-a-dictionary#988251). – Vasilis G. Aug 06 '18 at 11:55
  • it's just with os.getenv('options'). I have an environment variable that is equal to what I show as x. A string representation of a dict. – UCProgrammer Aug 06 '18 at 11:55
  • @VasilisG. I don't believe that would work since I'm using all single quotes. I get an invalid syntax error with it – UCProgrammer Aug 06 '18 at 11:58
  • Try `data["options"] = ast.literal_eval(data["options"][1:-1])`. I do not see any other way at this point. – Vasilis G. Aug 06 '18 at 12:01
  • How did you **create** this data? If you create it properly there is no need for this workaround. – Reut Sharabani Aug 06 '18 at 12:04
  • @ReutSharabani I passed along environment variables. This was my only option as far as receiving data. Another team of devs would have to fix their code so I could pass a dict from the start. – UCProgrammer Aug 06 '18 at 12:14
  • @UCProgrammer see my answer for my ideas. Also, environment variables usually work better as separate single values that you connect inside your context. – Reut Sharabani Aug 06 '18 at 12:37

2 Answers2

1
import ast

bad_string_dict = "'{'size':'Regular','connection':'unconnected'}'"
good_string_dict = bad_string_dict.strip("'")
good_dict = ast.literal_eval(good_string_dict)
print(good_dict)

You will have to strip quotation mark, no other way around

Adelina
  • 10,915
  • 1
  • 38
  • 46
  • I thought that strip() removed all instances of whatever chars you passed to it? Why do the single quotes surrounding the dict keys and values not get removed? – UCProgrammer Aug 06 '18 at 12:10
  • 1
    @UCProgrammer `strip() returns a copy of the string in which all chars have been stripped from the beginning and the end of the string` – Adelina Aug 06 '18 at 12:11
  • 1
    Thanks. I have no clue why but my brain completely left that part of strips() purpose out of my head. I was looking right at it here https://www.tutorialspoint.com/python/string_strip.htm and thought it was all characters. – UCProgrammer Aug 06 '18 at 12:18
0

Given OP's comments I suggest the following:

  1. Set the environment variable to a known data format (example: json/yaml/...), not a specific language (python)
  2. Use the json module (or the format you've chosen) to load the data

The data should look like this:

raw_data = {"test": "Fuzz", "options": "{\"size\": \"Regular\", \"connection\": \"unconnected\"}"}

And the code should look like this:

raw_options = raw_data['options']
options = json.loads(raw_options)
data = {**raw_data, 'options': options}
Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88