1

I have string

input_str = '{ "key1": 123, "key2": "val" }, { "key3": 345, "key4": {"key5": "val"} }'

I would like to split it into list by outermost curly brackets:

input_list = ['{ "key1": 123, "key2": "val" }', { "key3": 345, "key4": {"key5": "val"} }]

I wrote this code to obtain it:

input_str  = '{ "key1": 123, "key2": "val" }, { "key3": 345, "key4": {"key5": "val"} }' 
input_list = []
counter = 0
current_str = ''
for char in input_str:
  if char == '{':
    counter += 1
  if char == '}':
    counter -= 1
  if counter == 0:
    if current_str:
      current_str += char
      input_list.append(current_str)
      current_str = ''
  else:
    current_str += char
print(input_list)

Is there any more pythonic way to do it?

kekereke
  • 29
  • 2

1 Answers1

2

Since your input is a valid Python tuple of dicts and the expected output is a list of JSON strings, you can use ast.literal_eval to parse the string, and map each resulting sub-dict to json.dumps:

import ast
import json
print(list(map(json.dumps, literal_eval(input_str))))

This outputs:

['{"key1": 123, "key2": "val"}', '{"key3": 345, "key4": {"key5": "val"}}']
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • Thanks for answer but what should I do if it is not valid? Is there any option to check it? – kekereke Apr 09 '20 at 14:46
  • @kekereke You should include such a requirement in your question. Please update your question with a sample "invalid" input and how you want it handled. – blhsing Apr 09 '20 at 14:48
  • 2
    @JvdV `eval` is inherently insecure (as it allows arbitrary code execution) and doesn't actually produce the output the OP asks for. – blhsing Apr 09 '20 at 14:49
  • @JvdV Your output is *list of dictionaries* but OP wanted *list of strings* – Ch3steR Apr 09 '20 at 14:52