The other answers have explained why there's not an immediate infinite recursion issue (because generators are interpreted lazily). However, I think it is also interesting to consider when you might hit the finite limits on recursion that exist in the Python interpreter.
First off, I noticed that your code can be simplified a bit (you've got a couple more functions than are really needed, and your N
generator is identical to itertools.count(1)
). So here's a simpler version of your generator:
from itertools import count
def RZ():
x=count(1)
y=RZ()
while True:
yield next(x)
yield next(y)
Sample output:
>>> gen = RZ()
>>> for i in range(1, 21):
print i, next(gen)
1 1
2 1
3 2
4 1
5 3
6 2
7 4
8 1
9 5
10 3
11 6
12 2
13 7
14 4
15 8
16 1
17 9
18 5
19 10
20 3
Next, I wrote a function that introspects into the nested generators and counts how deeply they have been evaluated. I'm not sure if this code is portable between python versions (I'm using 2.7):
def getDepth(gen):
depth = 0
while gen:
depth += 1
gen = gen.gi_frame.f_locals.get("y")
return depth
Output from that (index, depth, value):
>>> for i in range(1, 21):
print i, getDepth(gen), next(gen)
1 1 1
2 2 1
3 3 2
4 3 1
5 4 3
6 4 2
7 4 4
8 4 1
9 5 5
10 5 3
11 5 6
12 5 2
13 5 7
14 5 4
15 5 8
16 5 1
17 6 9
18 6 5
19 6 10
20 6 3
Those depth values are growing logarithmically. Specifically, the depth of nested generators required to produce the Nth value of the sequence is ceil(log(N, 2)) + 1
.
In my copy of Python, recursion is allowed (by default) to go upto 100 levels deep. The generator will hit that limit only after 2^99 + 1 (=633,825,300,114,114,700,748,351,602,689) items have been produced. I wouldn't hold my breath waiting for that.