I was playing around with clever ways to create a python generator for sequence A003602
This appears to work, but I can't figure out why. It seems to me like it should hit infinite recursion. Is python doing some lazy evaluation somewhere that I don't recognize?
def N():
i=1
while True:
yield i
i+=1
def interleave(a,b):
def result():
x=a()
y=b()
while True:
yield next(x)
yield next(y)
return result
def RZ():
return interleave(N,RZ)()
gen=RZ()
To me it seems like since RZ instantly calls the method returned by interleave which in turn calls b which is RZ (before the first call to yield), this should be infinite recursion. But this actually seems to work. Can anyone explain why?
In most programming environments, a program with an infinite recursion will not really run forever. Eventually, something will break and the program will report an error. Infinite recursion is the first example we have seen of a run-time error (an error that does not appear until you run the program).
A recursive function is a function that makes a call to itself. To prevent infinite recursion, you need at least one branch (i.e. of an if/else statement) that does not make a recursive call. Branches without recursive calls are called base cases; branches with recursive calls are called recursive cases.
Every recursive function must have a base condition that stops the recursion or else the function calls itself infinitely. The Python interpreter limits the depths of recursion to help avoid infinite recursions, resulting in stack overflows. By default, the maximum depth of recursion is 1000 .
The “maximum recursion depth exceeded in comparison” error is raised when you try to execute a function that exceeds Python's built in recursion limit. You can fix this error by rewriting your program to use an iterative approach or by increasing the recursion limit in Python.
Generators (any function with a yield
statement) are lazy. This means that result()
will not start processing until you request the first value from it, which you don't do.
The root cause here is that you ask for a value from x
first. This means that the generator never gets to asking it's child generator until at least the second value asked for. Consider the simpler example:
def test():
yield 1
a = test()
while True:
yield next(a)
a = test()
for i in range(10):
print(next(a))
This works, just as yours does. It has the potential for infinite recursion, but will only get that far if you ask for that many values. All you have to do is remove the yield 1
to get the expected behaviour. In yours, just switch N
and RZ
and ask for the next value - you will get the expected recursion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With