def filter_object(obj, marks, presumption=DELETE):
if isinstance(obj, list):<EOL><INDENT>keys = reversed(range(<NUM_LIT:0>, len(obj)))<EOL><DEDENT>else:<EOL><INDENT>keys = list(obj.keys())<EOL><DEDENT>for k in keys:<EOL><INDENT>v = obj[k]<EOL>m = marks.get(id(v), UNSPECIFIED)<EOL>if m == DELETE:<EOL><INDENT>del obj[k]  <EOL><DEDENT>elif m == KEEP or presumption==KEEP:<EOL><INDENT>if isinstance(v, list) or isinstance(v, dict):<EOL><INDENT>filter_object(v, marks, presumption=KEEP)<EOL><DEDENT><DEDENT>elif m == UNSPECIFIED:<EOL><INDENT>if isinstance(v, list) or isinstance(v, dict):<EOL><INDENT>filter_object(v, marks, presumption=DELETE)<EOL>if len(v) == <NUM_LIT:0>:<EOL><INDENT>del obj[k]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>del obj[k]<EOL><DEDENT><DEDENT><DEDENT>
Filter down obj based on marks, presuming keys should be kept/deleted.

    Args:
        obj: The object to be filtered. Filtering is done in-place.
        marks: An object mapping id(obj) --> {DELETE,KEEP}
               These values apply to the entire subtree, unless inverted.
        presumption: The default action to take on all keys.