def WalkTree(top, getChildren: Callable = None, getFirstChild: Callable = None, getNextSibling: Callable = None, yieldCondition: Callable = None, includeTop: bool = False, maxDepth: int = <NUM_LIT>):
if maxDepth <= <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>depth = <NUM_LIT:0><EOL>if getChildren:<EOL><INDENT>if includeTop:<EOL><INDENT>if not yieldCondition or yieldCondition(top, <NUM_LIT:0>):<EOL><INDENT>yield top, <NUM_LIT:0>, <NUM_LIT:0><EOL><DEDENT><DEDENT>children = getChildren(top)<EOL>childList = [children]<EOL>while depth >= <NUM_LIT:0>:   <EOL><INDENT>lastItems = childList[-<NUM_LIT:1>]<EOL>if lastItems:<EOL><INDENT>if not yieldCondition or yieldCondition(lastItems[<NUM_LIT:0>], depth + <NUM_LIT:1>):<EOL><INDENT>yield lastItems[<NUM_LIT:0>], depth + <NUM_LIT:1>, len(lastItems) - <NUM_LIT:1><EOL><DEDENT>if depth + <NUM_LIT:1> < maxDepth:<EOL><INDENT>children = getChildren(lastItems[<NUM_LIT:0>])<EOL>if children:<EOL><INDENT>depth += <NUM_LIT:1><EOL>childList.append(children)<EOL><DEDENT><DEDENT>del lastItems[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>del childList[depth]<EOL>depth -= <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>elif getFirstChild and getNextSibling:<EOL><INDENT>if includeTop:<EOL><INDENT>if not yieldCondition or yieldCondition(top, <NUM_LIT:0>):<EOL><INDENT>yield top, <NUM_LIT:0><EOL><DEDENT><DEDENT>child = getFirstChild(top)<EOL>childList = [child]<EOL>while depth >= <NUM_LIT:0>:  <EOL><INDENT>lastItem = childList[-<NUM_LIT:1>]<EOL>if lastItem:<EOL><INDENT>if not yieldCondition or yieldCondition(lastItem, depth + <NUM_LIT:1>):<EOL><INDENT>yield lastItem, depth + <NUM_LIT:1><EOL><DEDENT>child = getNextSibling(lastItem)<EOL>childList[depth] = child<EOL>if depth + <NUM_LIT:1> < maxDepth:<EOL><INDENT>child = getFirstChild(lastItem)<EOL>if child:<EOL><INDENT>depth += <NUM_LIT:1><EOL>childList.append(child)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>del childList[depth]<EOL>depth -= <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>
Walk a tree not using recursive algorithm.
top: a tree node.
getChildren: function(treeNode) -> list.
getNextSibling: function(treeNode) -> treeNode.
getNextSibling: function(treeNode) -> treeNode.
yieldCondition: function(treeNode, depth) -> bool.
includeTop: bool, if True yield top first.
maxDepth: int, enum depth.

If getChildren is valid, ignore getFirstChild and getNextSibling,
    yield 3 items tuple: (treeNode, depth, remain children count in current depth).
If getChildren is not valid, using getFirstChild and getNextSibling,
    yield 2 items tuple: (treeNode, depth).
If yieldCondition is not None, only yield tree nodes that yieldCondition(treeNode, depth)->bool returns True.

For example:
def GetDirChildren(dir_):
    if os.path.isdir(dir_):
        return [os.path.join(dir_, it) for it in os.listdir(dir_)]
for it, depth, leftCount in WalkTree('D:\\', getChildren= GetDirChildren):
    print(it, depth, leftCount)