cartesian product of dict whose values are lists
    Args:
        d: dictionary to take product of. multiple dictionaries will first
           be merged by dict_merge
        kwargs: additional kwargs for convenience
    Returns:
        a list of dictionaries with the same keys as d and kwargs

def dict_product(*d, **kwargs):
    """
    cartesian product of dict whose values are lists
    Args:
        d: dictionary to take product of. multiple dictionaries will first
           be merged by dict_merge
        kwargs: additional kwargs for convenience
    Returns:
        a list of dictionaries with the same keys as d and kwargs
    """
    d = dict(dict_merge(*d), **kwargs)
    holdout = {k: d[k] for k in d if not isinstance(d[k], list)}
    d = {k: d[k] for k in d if k not in holdout}

    items = d.items()
    if len(items) == 0:
        dicts = [{}]
    else:
        keys, values = zip(*items)
        dicts = [dict_filter_none(dict(zip(keys, v))) for v in product(*values)]

    for d in dicts:
        d.update(holdout)

    return dicts