<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def remove_keys(d, keys=None, use_wildcards=True, list_of_dicts=False, deepcopy=True):
 """remove certain keys from nested dict, retaining preceeding paths Parameters keys: list use_wildcards : bool if true, can use * (matches everything) and ? (matches any single character) list_of_dicts: bool treat list of dicts as additional branches deepcopy: bool Examples -------- {1: 'A', 'b': 'B'} {'abc': 1} {} """

    keys = [] if keys is None else keys
    list_of_dicts = '__list__' if list_of_dicts else None

    def is_in(a, bs):
        if use_wildcards:
            for b in bs:
                try:
                    if a == b:
                        return True
                    if fnmatch(a, b):
                        return True
                except Exception:
                    pass
            return False
        else:
            try:
                return a in bs
            except Exception:
                return False

    if not hasattr(d, 'items'):
        return d
    else:
        dic = flatten(d, list_of_dicts=list_of_dicts)
        new_dic = {}
        for key, value in dic.items():
            new_key = tuple([i for i in key if not is_in(i, keys)])
            if not new_key:
                continue
            try:
                if new_key[-1].startswith(list_of_dicts):
                    continue
            except Exception:
                pass
            new_dic[new_key] = value
        return unflatten(
            new_dic, list_of_dicts=list_of_dicts, deepcopy=deepcopy)