0

I need to be able to convert any string in the format

"var1=var a;var2=var b"

to a dictionary and I managed to do that as follows.

a = "a=b;b=2"

def str_to_conf_dict(input_str):
    return dict(u.split('=') for u in input_str.split(';'))

b = str_to_conf_dict(a)
result= {'a': 'b', 'b': '2'}

But the values in the dictionary have quotes regardless whether var a, var b is a number or an alphabet.

I know that the values are always going to be a mix of characters and numbers (int/float/negatives). How would I have the quotes if the variable is a character and remove the quotes if it is a number?

It is crucial to have the quotes only on characters because I will pass the values to functions which work specifically if it meets the criteria, there is no way to modify that end.

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
  • 1
    loop through the dictionary, and use `try` `except` , if it will fail, it will go to the `except` block, where you will do nothing, and keep the character as is, and if successful, it becomes a number, reference : https://www.w3schools.com/python/python_try_except.asp – tsamridh86 Oct 09 '21 at 02:10

1 Answers1

1

Create a separate function for converting the value to its proper type.

Take a look at How to convert list of strings to their correct Python types?, where the answers use either ast.literal_eval or json.loads (amongst other solutions) to deserialize a string to a suitable Python object:

import json

def convert(val):
    try:
        return json.loads(val)
    except ValueError:
        return val  # return as-is

Then apply that function on each of the values from the original string.

def str_to_conf_dict(input_str):
    d = {}
    for pair in input_str.split(";"):
        k, v = pair.split("=")
        d[k] = convert(v)
    return d

s = "a=b;b=2;c=-3;d=xyz;e=4ajkl;f=3.14"
print(str_to_conf_dict(s))
{'a': 'b', 'b': 2, 'c': -3, 'd': 'xyz', 'e': '4ajkl', 'f': 3.14}

All the numbers (ints, floats, and negative ones) should be converted to numbers, while others are retained as-is (as strings, with quotes).

If you want to (unnecessarily) force it into a one-liner (for some reason), you'll need to setup a {key : convert(value)} dictionary comprehension. You can either .split twice to get each item of the pair:

def str_to_conf_dict(input_str):
    return {
        pair.split('=')[0]: convert(pair.split('=')[1])
        for pair in input_str.split(';')
    }

Or pair up the items from the .split('=') output. You can take inspiration from the pairwise recipe from the itertools package, or implement something simpler if you know the format is always going to be key=val:

def get_two(iterable):
    yield iterable[0], iterable[1]

def str_to_conf_dict(input_str):
    return { 
        k: convert(v) 
        for pair in input_str.split(';') 
        for k, v in get_two(pair.split('='))
    }
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135