human
Complete this python program:
def generic_multiedge_match(attr, default, op):
assistant
#Here is the Python program you requested.

    """Returns a comparison function for a generic attribute.
    The value(s) of the attr(s) are compared using the specified
    operators. If all the attributes are equal, then the constructed
    function returns True. Potentially, the constructed edge_match
    function can be slow since it must verify that no isomorphism
    exists between the multiedges before it returns False.
    Parameters
    attr : string | list
    The edge attribute to compare, or a list of node attributes
    to compare.
    default : value | list
    The default value for the edge attribute, or a list of
    default values for the dgeattributes.
    op : callable | list
    The operator to use when comparing attribute values, or a list
    of operators to use when comparing values for each attribute.
    Returns
    match : function
    The customized, generic `edge_match` function.
    Examples
    >>> from operator import eq
    >>> from networkx.algorithms.isomorphism.matchhelpers import close
    >>> from networkx.algorithms.isomorphism import generic_node_match
    >>> nm = generic_node_match(\weight\, 1.0, close)
    >>> nm = generic_node_match(\color\, \red\, eq)
    >>> nm = generic_node_match([\weight\, \color\],
    ...                         [1.0, \red\],
    ...                         [close, eq])
    """
    if nx.utils.is_string_like(attr):
        attr = [attr]
        default = [default]
        op = [op]
    attrs = list(zip(attr, default))
    def match(datasets1, datasets2):
        values1 = []
        for data1 in datasets1.values():
            x = tuple((data1.get(attr, d) for (attr, d) in attrs))
            values1.append(x)
        values2 = []
        for data2 in datasets2.values():
            x = tuple((data2.get(attr, d) for (attr, d) in attrs))
            values2.append(x)
        for vals2 in permutations(values2):
            for (xi, yi) in zip(values1, vals2):
                if (not all(map((lambda x, y, z: z(x, y)), xi, yi, op))):
                    break
            else:
                return True
        else:
            return False
    return match