In python I receive the following datastructure from a database:
{
"field":"Somestring/somestring.jpg?<<TOKEN>>",
"list": [
{"field": "sometring.html?<<TOKEN>>"},
{"field2": "otherstring.mp4?<<TOKEN>>"}
]
}
And this structure might very well be expanded to include more lists with fields.
I wish to replace all instances of "<<TOKEN>>" that appear in different strings throughout my data structure, with a validation token used in other to acces the urls that these strings represent.
Is there a better way to do this, than accesing each field with a loop, checking if its a string, and thereafter running: field.replace("<<TOKEN>>", my_token)
CodePudding user response:
Recursive approach
This works like a walker, go inside at each level of the data structure and apply the cure handling the correct type. This let you to handle special cases too or particular data types.
var = {
"field":"Somestring/somestring.jpg?<<TOKEN>>",
"list": [
{"field": "sometring.html?<<TOKEN>>"},
{"field2": "otherstring.mp4?<<TOKEN>>"}
]
}
def replacer(obj, val:str):
if isinstance(obj, str):
return obj.replace('<<TOKEN>>', val)
if isinstance(obj, list):
return [replacer(x,val) for x in obj]
if isinstance(obj, dict):
return {k:replacer(x,val) for k,x in obj.items()}
# other cases
#if ...
return obj
replacer(var, 'ciao')
#{'field': 'Somestring/somestring.jpg?ciao',
# 'list': [{'field': 'sometring.html?ciao'},
# {'field2': 'otherstring.mp4?ciao'}]}
Using a serializer
as told by @Mahrkeenerh (kudos) This is a trick, the json-fied version is a string too, so result more performing to do a single replace.
serialize -> cure -> deserialize
import json
json.loads(json.dumps(var).replace('<<TOKEN>>', 'ciao'))
#{'field': 'Somestring/somestring.jpg?ciao',
# 'list': [{'field': 'sometring.html?ciao'},
# {'field2': 'otherstring.mp4?ciao'}]}