Home > Net >  Best way to .replace() all instances of a String in a dictionary
Best way to .replace() all instances of a String in a dictionary

Time:10-29

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'}]}
  • Related