7

I have a function that its called recursively. When I run it I get the error "maximum recursion depth exceeded while calling a Python object"

How can increase the limit on mac? If I use the following, I get the error "cannot increase the limit on mac"

resource.setrlimit(resource.RLIMIT_STACK, (2**24,-1))
sys.setrecursionlimit(10**6)
7
  • This might be a Python limitation, not something to do with Mac. Commented Mar 17, 2016 at 18:45
  • Have you considered the possibility of rewriting your recursion to have log stack growth rather than linear stack growth? For example, finding the max of a list can be set up recursively by comparing the max so far to the max of the rest of the list, but the stack will grow linearly in the size of the list. A better solution is to find the max of the first half of the list and the second half of the list, and take the larger of those two, which doesn't do any less work but grows the stack logarithmically in the size of the list. Perhaps your problem can be recast similarly. Commented Mar 17, 2016 at 18:46
  • 1
    Interesting @pjs , Do you have an example of that by chance? Commented Mar 17, 2016 at 18:56
  • I'm working on an answer, but it is really long, stand by... Commented Mar 17, 2016 at 19:03
  • @Goodies Yes, I do. But it's impossible to say whether the same approach will work for nbrugir without seeing code. Commented Mar 17, 2016 at 19:08

1 Answer 1

1

I had a problem where I had the possibility of recurring several billions of times, and the way I did it was by flattening the recursion. I don't know if this method has been documented before, because I came up with it on my own instead of finding it. All you really have to do is put the local namespace of each function in a list. This will require a change in your actual code, if there is no workaround. Here's how it works:

Say I have this function:

def flatten_a_list(obj):#[[6,5],7,[3,[9,0]]] -> [6,5,7,3,9,0]
    flattened = []
    for item in obj:
        if type(item) == list:
            flattened.append(flatten_a_list(item))
        else:
            flattened.append(item)
    return flattened

Now, this is traditionally recursive. To make it so that it will work for however many nestings there are with no limit, I would do this:

from copy import deepcopy

def improved(obj):#[[6,5],7,[3,[9,0]]] -> [6,5,7,3,9,0]
    flattened = []
    position = [0]
    while True:
        print('position: {}'.format(str(position)))
        x = deepcopy(obj)
        try:
            for index in position:
                x = x[index]
        except (IndexError, TypeError):
            break

        if type(x) == list:
            position.append(0)
            print('continuing')
            continue
        else:
            flattened.append(x)

        #Test the next position
        test = deepcopy(position)
        test[-1] += 1
        x = deepcopy(test)
        print('x: {}'.format(x))
        try:
            y = deepcopy(obj)
            for index in x:
                y = y[index]
            position = deepcopy(test)
        except (IndexError, TypeError):
            position = position[:-1]
            try:
                position[-1] += 1
            except IndexError:
                break

    return flattened

Two words: Mind Bending

The function I wrote works fine, but it is unoptimized. If you want speed, first make sure you understand the function, then combine the checkings of index overflow by taking the 'x' and 'y' blocks of code are polymorphesizing them.

You will have to adapt this to your code, but as long as you understand it, it shouldn't be much or a problem. Plus, the answer is cross platform and unlimited.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.