Skip to content

Commit d089f12

Browse files
Add getting around recursion limit vid
1 parent 4870144 commit d089f12

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ James and his team are available for consulting, contracting, code reviews, and
1212

1313
| N | Code | Video |
1414
| -- | --- |--- |
15+
| 113 | [src](videos/113_getting_rid_of_recursion) | [Getting around the recursion limit](https://youtu.be/1dUpHL5Yg8E) |
1516
| 112 | [src](videos/112_python_name_mangling) | [Every Python dev falls for this (name mangling)](https://youtu.be/0hrEaA3N3lk) |
1617
| 111 | [src](videos/111_python_closures) | [Functions within functions, closures, and variable scopes in Python](https://youtu.be/jXugs4B3lwU) |
1718
| 110 | [src](videos/110_rvo_and_copy_elision) | [Return Value Optimization and Copy Elision in C++](https://youtu.be/HNYOx-Vh_VA) |
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
from __future__ import annotations
2+
3+
4+
class Node:
5+
def __init__(self, *children: Node, data=None):
6+
self.children = list(children)
7+
self.data = data
8+
9+
def __repr__(self):
10+
return f'({self.data})'
11+
12+
13+
# initial recursive implementation
14+
def print_parent_then_children(node: Node):
15+
print(node)
16+
for child in node.children:
17+
print_parent_then_children(child)
18+
19+
20+
# first try using stack
21+
def print_parent_then_children(node: Node):
22+
stack = [node]
23+
24+
while stack:
25+
node = stack.pop()
26+
print(node)
27+
for child in node.children:
28+
stack.append(child)
29+
30+
31+
# fixed issue with order of pushing onto stack
32+
def print_parent_then_children(node: Node):
33+
stack = [node]
34+
35+
while stack:
36+
node = stack.pop()
37+
print(node)
38+
for child in reversed(node.children):
39+
stack.append(child)
40+
41+
42+
# recursive implementation with max depth
43+
def print_parent_then_children(node: Node, max_depth=-1):
44+
print(node)
45+
if max_depth == 0:
46+
return
47+
for child in node.children:
48+
print_parent_then_children(child, max_depth - 1)
49+
50+
51+
# stack version with max depth
52+
def print_parent_then_children(node: Node, max_depth=-1):
53+
stack = [(node, max_depth)]
54+
while stack:
55+
node, max_depth = stack.pop()
56+
print(node)
57+
if max_depth == 0:
58+
continue
59+
for child in reversed(node.children):
60+
stack.append((child, max_depth - 1))
61+
62+
63+
# factor out the iteration
64+
def walk_parent_then_children(node: Node, max_depth=-1):
65+
stack = [(node, max_depth)]
66+
while stack:
67+
node, max_depth = stack.pop()
68+
yield node
69+
if max_depth == 0:
70+
continue
71+
for child in reversed(node.children):
72+
stack.append((child, max_depth - 1))
73+
74+
75+
# decoupled implementation
76+
def print_parent_then_children(node: Node, max_depth=-1):
77+
for node in walk_parent_then_children(node, max_depth):
78+
print(node)
79+
80+
81+
# root -> child 0 -> child 1 -> ...
82+
def long_tree_example():
83+
root = Node(data="root")
84+
node = root
85+
for n in range(1000):
86+
new = Node(data=f"child {n}")
87+
node.children.append(new)
88+
node = new
89+
90+
print_parent_then_children(root)
91+
92+
93+
# root
94+
# child 0 child 1
95+
# 0-0 0-1 0-2
96+
def small_example():
97+
root = Node(
98+
Node(
99+
Node(data="child 0-0"),
100+
Node(data="child 0-1"),
101+
Node(data="child 0-2"),
102+
data="child 0",
103+
),
104+
Node(data="child 1"),
105+
data="root",
106+
)
107+
108+
print_parent_then_children(root)
109+
print(list(walk_parent_then_children(root, max_depth=1)))
110+
111+
112+
def main():
113+
small_example()
114+
long_tree_example()
115+
116+
117+
if __name__ == '__main__':
118+
main()

0 commit comments

Comments
 (0)