Skip to content Skip to sidebar Skip to footer

How To Replace All Instances Of A Keyword In Arbitrarily Structured Data?

I want to replace kw's in a dict which may have complex structure (e.g the values may be dicts or lists. Those dicts should also get their kw's replaced and the list elements may b

Solution 1:

json

A quick-n-simple solution involves converting the entire thing to a string with json, using re.sub and then converting it back:

import json, re
json.loads(re.sub('(?<=")bbox_xywh(?=":)', 'bbox', json.dumps(d), flags=re.M))

{'data': [{'bbox': [838, 533, 50, 68], 'object': 'truck'},
  {'bbox': [930, 563, 60, 57], 'object': 'car'},
  {'bbox': [993, 560, 78, 56], 'object': 'car'},
  {'bbox': [997, 565, 57, 39], 'object': 'car'},
  {'bbox': [1094, 542, 194, 126], 'object': 'car'},
  {'bbox': [1311, 539, 36, 74], 'object': 'person'}],
 'dimensions_h_w_c': [1200, 1920, 3],
 'filename': '/data/jeremy/image_dbs/hls/voc_rio_udacity_kitti_insecam_shuf_no_aug_test/1478020901220540088.jpg'}

You may also consider using str.replace instead of regex (slightly faster):

json.loads(json.dumps(d).replace('"bbox_xywh":', '"bbox":'))

Have faith in json that it stringifies your data consistently. You can handle dictionarys of arbitrary structure like this.

This fails when your data isn't JSON compliant - if you have other python objects besides lists and dicts or custom class objects, this no longer works.


literal_eval

Here's another method with ast.literal_eval to overcome the problem mentioned above:

import ast
ast.literal_eval(str(d).replace('\'bbox_xywh\':', '\'bbox\':'))

While it does not coerce tuples to lists, I'm not a fan of this because the quotes have to be treated very carefully.

Solution 2:

defrep_str(obj, replace_this, with_this):
    ifisinstance(obj, str):
        return obj.replace(replace_this, with_this)
    return obj

defchange(obj, replace_this, with_this):
    ifisinstance(obj, list):
        return [change(x, replace_this, with_this) for x in obj]
    ifisinstance(obj, dict):
        return {rep_str(k, replace_this, with_this): 
            change(v, replace_this, with_this) for k, v in obj.items()}
    return obj

change(obj, replace_this, with_this)

Post a Comment for "How To Replace All Instances Of A Keyword In Arbitrarily Structured Data?"