2. I don't see why `del jsonobject[...]` would be necessary before reassigning that key. Also, the test in the last two lines could also be simplified to something like `jsonobject.pop('small_encoded_polyline', None)` if you don't care about that key, no? Also: - Everything could use more error checking. That is, check expected types and values instead of falling through the `if`s (`'imperial'`, `'metric'`, what happens if it's neither, or both?). - Unless you really prefer `list` and `dict`, it's better to use the literal syntax `[]` and `{}` (the names could be shadowed by some definition). - The type check for `dict`s can be better, i.e. `isinstance(foo, dict)`; if you really want *only* `dict`, then it's still better to use `type(foo) is dict` instead of comparing strings. I'd also move that whole `if/else` into a function, e.g. `maybe_load_json` or so. - The value of `document` after the assignments isn't used anywhere, so it's safe to remove, though I'd rather use that variable again instead of introducing `document2`. - The second branch with `'small_encoded_polyline'` seems to have the wrong level of indentation? At least it's different from the first one in that it's only run if the document wasn't a `dict`. Assuming that it's safe to run anyway I'll change that in the code below. - The pattern `if foo in json and json[foo] is not None:` could be easier be achieved with `if json.get(foo) is not None:` as the return value there defaults to `None`. - I'm not particularly fond of the habit to reuse input data like with `'points_correct'` done here. It would be cleaner just to have a list `points_correct` and assign that to a `jsonobject` key (and you know, possibly put the calculation into a separate function as well). I might have messed up some of the logic now, but I hope you get the idea: def maybe_load_json(document): if isinstance(document, dict): return document return json.loads(document) def cleaned_small_encoded_polylines(documents): result = [] for document in documents: #sometimes these document objects turn out to be dicts #and sometimes they turn out to be strings #even though JSON output is always the same #is there a better way to deal with this? document = maybe_load_json(document) if document.get('small_encoded_polyline') is not None: del document['small_encoded_polyline'] #I thought this line above would modify the original #jsonobject since document is a dictionary so I should #be working with a pointer to the original object #but inspection of jsonobject reveals this not to be the case result.append(document) return result ... r = requests.get(url, headers = {'User-Agent':UA}) jsonobject = r.json() if jsonobject.get('laps') is not None: if 'imperial' in jsonobject['laps']: laps_array = jsonobject['laps']['imperial'] type = 'imperial' if 'metric' in jsonobject['laps']: laps_array = jsonobject['laps']['metric'] type = 'metric' if laps_array is not None: jsonobject['laps'][type] = cleaned_small_encoded_polylines(laps_array) # this can't be an elif because sometimes json objects # have both "points" and "laps" if jsonobject.get('points') is not None: if 'points' in jsonobject['points']: points_correct = [] laps_array = jsonobject['points']['points'] if laps_array is not None: jsonobject['points']['points'] = cleaned_small_encoded_polylines(laps_array) jsonobject.pop('small_encoded_polyline', None)