Recursion and breaking out of (or ignoring) a cycle
<p>I have the following:</p>

<pre><code>def rfunction(x, y):
    new_x = assignment1
    new_y = assignment2
    print "x depends on new_x of form y"
    rfunction(new_x, new_y)
</code></pre>

<p>My true code is a lot more complex, relies on multiple jsons, etc. but this is the gist of the issue. Running this will yield pleasant results, up until I get the following output: <code>x depends on x of label y</code>, and of course run into an infinite loop. How can I ensure this prints once, and then break (or ignore) the recursion, and continue on. The structure of what I'm recursing over is a dependency graph in which arcs only flow downward toward children, but nodes may have a loop. It's this existence of a loop which is throwing me off.</p>

<p>If the only cycles you might encounter are self-references (e.g. <code>new_x, new_y</code> is <code>x, y</code>), then you could fix this with a simple <code>if</code> check:</p>

<pre><code>def rfunction(x, y):
    new_x = assignment1
    new_y = assignment2
    print "x depends on new_x of form y"
    if new_x != x or new_y != y:
        rfunction(new_x, new_y)
    else:
        do_something_else() # or maybe just return?
</code></pre>

<p>If you need to be concerned about more indirect cycles (e.g. <code>rfunction(1, 1)</code> calls <code>rfunction(1, 2)</code>, which calls <code>rfunction(1, 1)</code> again), you need to keep track of the parameter pairs you've seen before. Here's one way to do that with a <code>set</code>:</p>

<pre><code>def rfunction(x, y, seen=None):
    if seen is None:
        seen = set()
    seen.add((x, y))
    new_x = assignment1
    new_y = assignment2
    print "x depends on new_x of form y"
    if (new_x, new_y) not in seen:
        rfunction(new_x, new_y, seen)
    else:
        do_something_else()
</code></pre>

<p>I'd note that neither of these code examples have a base case (other than the recursive cycle that I'm breaking). Presumably your real code does, so I'll leave it up to you to include it as you adapt my examples to fit your code.</p>

python recursion infinite-loop