def depth_first_ordering(adjacency, root):
    """Compute depth-first ordering of connected vertices.

    Parameters
    ----------
    adjacency : dict
        An adjacency dictionary. Each key represents a vertex
        and maps to a list of neighboring vertex keys.
    root : str
        The vertex from which to start the depth-first search.

    Returns
    -------
    list
        A depth-first ordering of all vertices in the network.

    Notes
    -----
    Return all nodes of a connected component containing 'root' of a network
    represented by an adjacency dictionary.

    This implementation uses a *to visit* stack. The principle of a stack
    is LIFO. In Python, a list is a stack.

    Initially only the root element is on the stack. While there are still
    elements on the stack, the node on top of the stack is 'popped off' and if
    this node was not already visited, its neighbors are added to the stack if
    they hadn't already been visited themselves.

    Since the last element on top of the stack is always popped off, the
    algorithm goes deeper and deeper in the datastructure, until it reaches a
    node without (unvisited) neighbors and then backtracks. Once a new node
    with unvisited neighbors is found, there too it will go as deep as possible
    before backtracking again, and so on. Once there are no more nodes on the
    stack, the entire structure has been traversed.

    Note that this returns a depth-first spanning tree of a connected component
    of the network.

    Examples
    --------
    >>> import compas
    >>> from compas.datastructures import Network
    >>> from compas.topology import depth_first_search as dfs
    >>> network = Network.from_obj(compas.get('lines.obj'))
    >>> print(dfs(network, network.get_any_vertex()))

    See Also
    --------
    *

    """
    adjacency = {key: set(nbrs) for key, nbrs in iter(adjacency.items())}
    tovisit = [root]
    visited = set()
    ordering = []

    while tovisit:
        # pop the last added element from the stack
        node = tovisit.pop()

        if node not in visited:
            # mark the node as visited
            visited.add(node)
            ordering.append(node)
            # add the unvisited nbrs to the stack
            tovisit.extend(adjacency[node] - visited)

    return ordering