def remove_keyvals(d, keyvals=None, list_of_dicts=False, deepcopy=True):
    """remove paths with at least one branch leading
    to certain (key,value) pairs from dict

    Parameters
    ----------
    d : dict
    keyvals : dict or list[tuple]
        (key,value) pairs to remove
    list_of_dicts: bool
        treat list of dicts as additional branches

    Examples
    --------

    >>> from pprint import pprint
    >>> d = {1:{"b":"A"},"a":{"b":"B","c":"D"},"b":{"a":"B"}}
    >>> pprint(remove_keyvals(d,[("b","B")]))
    {1: {'b': 'A'}, 'b': {'a': 'B'}}

    >>> d2 = {'a':[{'b':1,'c':1},{'b':1,'c':2}]}
    >>> pprint(remove_keyvals(d2,[("b",1)]))
    {'a': [{'b': 1, 'c': 1}, {'b': 1, 'c': 2}]}

    >>> pprint(remove_keyvals(d2,[("b",1)],list_of_dicts=True))
    {}

    """
    keyvals = [] if keyvals is None else keyvals
    list_of_dicts = '__list__' if list_of_dicts else None

    if hasattr(keyvals, 'items'):
        keyvals = [(k, v) for k, v in keyvals.items()]

    if not hasattr(d, 'items'):
        return d

    flatd = flatten(d, list_of_dicts=list_of_dicts)

    def is_in(a, b):
        try:
            return a in b
        except Exception:
            return False

    prune = [k[0] for k, v in flatd.items() if is_in((k[-1], v), keyvals)]
    flatd = {k: v for k, v in flatd.items() if not is_in(k[0], prune)}

    return unflatten(flatd, list_of_dicts=list_of_dicts, deepcopy=deepcopy)