I'm having problem translating my JavaScript snippet to Python.
The JavaScript code looks like this:
const reviver = (_key, value) => {
try {
return JSON.parse(value, reviver);
} catch {
if(typeof value === 'string') {
const semiValues = value.split(';');
if(semiValues.length > 1) {
return stringToObject(JSON.stringify(semiValues));
}
const commaValues = value.split(',');
if(commaValues.length > 1) {
return stringToObject(JSON.stringify(commaValues));
}
}
const int = Number(value);
if(value.length && !isNaN(int)) {
return int;
}
return value;
}
};
const stringToObject = (str) => {
const formatted = str.replace(/"{/g, '{').replace(/}"/g, '}').replace(/"\[/g, '[').replace(/\]"/g, ']').replace(/\\"/g, '"');
return JSON.parse(formatted, reviver);
};
The goal of the function is that:
- String values that are numbers are parsed
- String values that are json are parsed using these rules
- String values like
"499,504;554,634"
should be parsed to[(499, 504), (554, 634)]
I have tried using the JSONDecoder.
import json
def object_hook(value):
try:
return json.loads(value)
except:
if(isinstance(value, str)):
semiValues = value.split(';')
if(len(semiValues) > 1):
return parse_response(json.dumps(semiValues))
commaValues = value.split(',')
if(commaValues.length > 1):
return parse_response(json.dumps(commaValues))
try:
return float(value)
except ValueError:
return value
def parse_response(data: str):
formatted = data.replace("\"{", "{").replace("}\"", '}').replace("\"[", '[').replace("]\"", ']').replace("\\\"", "\"")
return json.load(formatted, object_hook=object_hook)
CodePudding user response:
Your Python code looks like it's on the right track, but there are a few issues with it. First, you're using commaValues
.length instead of len(commaValues)
in the if statement that checks if the length of commaValues
is greater than 1
. Second, json.load()
expects a file-like object as its first argument, not a string. You can use json.loads()
instead to parse a JSON string.
Here's how I would write the code in Python:
import json
def reviver(key, value):
try:
return json.loads(value, reviver=reviver)
except:
if isinstance(value, str):
semiValues = value.split(';')
if len(semiValues) > 1:
return stringToObject(json.dumps(semiValues))
commaValues = value.split(',')
if len(commaValues) > 1:
return stringToObject(json.dumps(commaValues))
try:
return int(value)
except ValueError:
return value
def stringToObject(str):
formatted = str.replace('"{', '{').replace('}"', '}').replace('"[', '[').replace(']"', ']').replace('\\"', '"')
return json.loads(formatted, reviver=reviver)
Note that I also changed the try statement that tries to convert the string to a number to use int()
instead of float()
to parse the value as an integer instead of a floating-point number. I also changed the function and variable names to follow the Python convention of using lowercase words separated by underscores (e.g. string_to_object
instead of stringToObject
).
CodePudding user response:
I solved my issue by iterating through the values and parse them accordingly
def parse_value(value):
if(isinstance(value, str)):
try:
return parse_value(json.loads(value))
except:
pass
semi_values = value.split(';')
if(len(semi_values) > 1):
return list(map(parse_value, semi_values))
comma_values = value.split(',')
if(len(comma_values) > 1):
return list(map(parse_value, comma_values))
if(value.replace('.','',1).isdigit()):
return int(value)
if(isinstance(value, dict)):
return {k: parse_value(v) for k, v in value.items()}
if(isinstance(value, list)):
return list(map(parse_value, value))
return value
CodePudding user response:
Does this code works for you?
def reviver(_key, value):
try:
return json.loads(value, object_hook=reviver)
except:
if type(value) == str:
semi_values = value.split(';')
if len(semi_values) > 1:
return string_to_object(json.dumps(semi_values))
comma_values = value.split(',')
if len(comma_values) > 1:
return string_to_object(json.dumps(comma_values))
int_val = int(value)
if len(value) and not isinstance(int_val, int):
return int_val
return value
def string_to_object(str):
formatted = str.replace('"{', '{').replace('}"', '}').replace('"[', '[').replace(']"', ']').replace('\\"', '"')
return json.loads(formatted, object_hook=reviver)