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)
nabrugir
  • 1,839
  • 2
  • 22
  • 38
  • This might be a [Python limitation](http://stackoverflow.com/a/6809586/3872894), not something to do with Mac. – Jared Hooper Mar 17 '16 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. – pjs Mar 17 '16 at 18:46
  • 1
    Interesting @pjs , Do you have an example of that by chance? – Goodies Mar 17 '16 at 18:56
  • I'm working on an answer, but it is really long, stand by... – Nick Pandolfi Mar 17 '16 at 19:03
  • @Goodies [Yes, I do](http://stackoverflow.com/questions/35893550/finding-the-max-item-in-a-sequence-using-recursion/35895476#35895476). But it's impossible to say whether the same approach will work for nbrugir without seeing code. – pjs Mar 17 '16 at 19:08
  • If you search for a related error there are lots of suggested fixes on superuser but the best solution to your problem would be to write an iterative algorithm if possible. – Padraic Cunningham Mar 17 '16 at 19:38
  • How is my answer? Did it not work? Did you just feel like not trying it? Any feedback? – Nick Pandolfi Mar 24 '16 at 14:45

1 Answers1

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.

Nick Pandolfi
  • 993
  • 1
  • 8
  • 22