-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathrecursing-with-yield.html
86 lines (81 loc) · 2.96 KB
/
recursing-with-yield.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<title>leontrolski - Recursing with yield</title>
<style>
body {margin: 5% auto; background: #fff7f7; color: #444444; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.8; max-width: 63%;}
@media screen and (max-width: 800px) {body {font-size: 14px; line-height: 1.4; max-width: 90%;}}
pre {width: 100%; border-top: 3px solid gray; border-bottom: 3px solid gray;}
a {border-bottom: 1px solid #444444; color: #444444; text-decoration: none;text-shadow: 0 1px 0 #ffffff;}
a:hover {border-bottom: 0;}
</style>
<link href="https://unpkg.com/[email protected]/themes/prism-vs.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/components/prism-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/autoloader/prism-autoloader.min.js"></script>
</head>
<body class="language-python">
<a href="index.html"><img style="height:2em" src="pic.png"/>⇦</a>
<p><i>2020-08-21</i></p>
<h1>Recursing with <code>yield</code></h1>
<p>
This post shows a simple <code>python</code>/<code>js</code> pattern for recursing through code that probably should get a bit more usage.
</p>
<p>
Say you have the following data:
</p>
<pre><code>tree = {
"a": 4,
"children": [
{
"a": 3,
"children": []
},
{
"a": 2,
"children": [
{
"a": 6,
"children": []
}
]
},
]
}</code></pre>
<p>
And you want to get all the <code>a</code> values greater than 2.
</p>
<p>
In <code>python</code>, the "classic" way would be to do:
</p>
<pre><code>def greater_than_2(t):
a, children = t["a"], t["children"]
accumulated = ()
if a > 2:
accumulated += (a, )
for child in children:
accumulated += greater_than_2(child)
return accumulated
greater_than_2(tree)</code></pre>
<p>
That will give you: <code>(4, 3, 6)</code>.
</p>
<p>
I find it is often more natural to use <code>yield</code>:
</p>
<pre><code>def greater_than_2(t):
a, children = t["a"], t["children"]
if a > 2:
yield a
for child in children:
yield from greater_than_2(child)
tuple(greater_than_2(tree))</code></pre>
<p>
A near identical solution can be achieved with modern <code>js</code> (this may surprise any <code>python</code> devs that haven't seen the language for a while 😊 ):
</p>
<pre><code class="language-javascript">function* greater_than_2(t){
const {a, children} = t
if (a > 2) yield a
for (const child of children) yield* greater_than_2(child)
}
[...greater_than_2(tree)]
</code></pre>
</body>