Let's say I implemented a simple version of an iterative DFS like this:
import sys
import traceback
def dfs(graph, start):
    visited, stack = [], [start]
    while stack:
        node = stack.pop()
        if node not in visited:
            visited.append(node)
            childs = reversed(graph.get(node, list()))
            stack.extend([item for item in childs if item not in visited])
    return visited
if __name__ == "__main__":
    graphs = [
        {
            'A': ['B', 'C'],
            'B': ['D']
        }
    ]
    for i, g in enumerate(graphs):
        try:
            print "{0}Graph {1}{2}".format('-' * 40, i, '-' * 33)
            for f in [dfs]:
                print f.__name__, '-->', f(g, 'A')
                print '-' * 80
        except Exception as e:
            print "Exception in user code: {0}".format(e)
            print '-' * 60
            traceback.print_exc(file=sys.stdout)
            print '-' * 60
The output of the above snippet is this:
----------------------------------------Graph 0---------------------------------
dfs --> ['A', 'B', 'D', 'C']
--------------------------------------------------------------------------------
Now, I'm trying to figure out how to get the following output (instead running node's method just printing is fine):
A_start, B_start, D_start, D_end, B_end, A_middle, C_start, C_end, A_end
*_middle will only be executed between subnodes execution. For instance, if a node doesn't have any subnodes, or has only a single one, it never gets executed. That's why my desired output only has A_middle (none of the B_middle, C_middle, D_middle) in the above example.
How can I do this?
EDIT:
Trying to find the recursive solution to my problem:
def dfs(graph, node):
    if node not in graph:
        return
    print '{0}_start'.format(node)
    for i, node in enumerate(graph[node]):
        if i > 0:
            print '{0}_middle'.format(node)
        dfs(graph, node)
    print '{0}_end'.format(node)
if __name__ == "__main__":
    graphs = [
        {
            'A': ['B', 'C'],
            'B': ['D']
        }
    ]
    for i, g in enumerate(graphs):
        try:
            print "{0}Graph {1}{2}".format('-' * 40, i, '-' * 33)
            for f in [dfs]:
                print f.__name__, '-->'
                f(g, 'A')
                print '-' * 80
        except Exception as e:
            print "Exception in user code: {0}".format(e)
            print '-' * 60
            traceback.print_exc(file=sys.stdout)
            print '-' * 60
Will give me the wrong output:
----------------------------------------Graph 0---------------------------------
dfs -->
A_start
B_start
D_end
C_middle
C_end
--------------------------------------------------------------------------------