def node_intersection(graphs):
    """Take the node intersection over a collection of graphs into a new graph.

    This intersection is defined the same way as by :func:`left_node_intersection_join`

    :param iter[BELGraph] graphs: An iterable of graphs. Since it's iterated over twice, it gets converted to a
     tuple first, so this isn't a safe operation for infinite lists.
    :rtype: BELGraph

    Example usage:

    >>> import pybel
    >>> g = pybel.from_path('...')
    >>> h = pybel.from_path('...')
    >>> k = pybel.from_path('...')
    >>> merged = node_intersection([g, h, k])
    """
    graphs = tuple(graphs)

    n_graphs = len(graphs)

    if n_graphs == 0:
        raise ValueError('no graphs given')

    if n_graphs == 1:
        return graphs[0]

    nodes = set(graphs[0].nodes())

    for graph in graphs[1:]:
        nodes.intersection_update(graph)

    return union(
        subgraph(graph, nodes)
        for graph in graphs
    )
Take the node intersection over a collection of graphs into a new graph.

    This intersection is defined the same way as by :func:`left_node_intersection_join`

    :param iter[BELGraph] graphs: An iterable of graphs. Since it's iterated over twice, it gets converted to a
     tuple first, so this isn't a safe operation for infinite lists.
    :rtype: BELGraph

    Example usage:

    >>> import pybel
    >>> g = pybel.from_path('...')
    >>> h = pybel.from_path('...')
    >>> k = pybel.from_path('...')
    >>> merged = node_intersection([g, h, k])