Last active
November 3, 2021 02:05
-
-
Save wrouesnel/10db40ac02483af905d91d200961fc0f to your computer and use it in GitHub Desktop.
Simple function for recursively iterating JSON-like data in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections.abc import Mapping | |
from typing import Any, Callable, Iterable, MutableMapping, MutableSequence | |
def recurse_object(o: Any, | |
k=None, | |
fn: Callable[[Any,Any,Any],Any]=None, | |
prefn:Callable[[Any,Any],None]=None, | |
postfn:Callable[[Any,Any,Any,Any],Any]=None, | |
mapping_cls=dict, | |
sequence_cls=list) -> Any: | |
""" | |
Recurse through an object and apply a function to every key level. | |
Only applicable to Mapping/Sequence types. | |
:param o: (any) object to recurse through | |
:param k: (any) key path of the value that provided the object just requested | |
:param fn: fn which manipulates the value | |
:param prefn: prefn called before recursing | |
:param postfn: postfn called before returning | |
:param mapping_cls: class initializer for mapping types | |
:param sequence_cls: class initializer for sequence types | |
:return: | |
""" | |
if fn is None: | |
fn = lambda i, k, o: i | |
if prefn is not None: | |
i = prefn(o,k) | |
else: | |
i = o | |
r: Any = None | |
if isinstance(i, Mapping): | |
r: MutableMapping = mapping_cls() | |
for k,v in i.items(): | |
r[k] = recurse_object(v, k, fn=fn, prefn=prefn, postfn=postfn) | |
elif isinstance(i, Iterable) and not isinstance(i, (str,bytes)): | |
r: MutableSequence = sequence_cls() | |
for k,v in enumerate(i): | |
r.append(recurse_object(v, k, fn=fn, prefn=prefn, postfn=postfn)) | |
else: | |
r = fn(i,k,o) | |
if postfn is not None: | |
r = postfn(o,k,i,r) | |
return r |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment