0

Appreciate you looking at this. As title suggests, I am trying to get the nth application of a function.

The first implementation works, however, the second implementation does not. Could someone point me to the reason why? I am using Python 3.4 if that makes a difference.

First implementation:

def repeated(f,n):
    def value(x):
        k=n
        while k>=1:
            x=f(x)
            k=k-1
        return x
    return value

Second implementation:

def repeated1(f,n):
    def value(x):
        while n>=1:
            x=f(x)
            n=n-1
        return x
    return value

Error is local variable n is referenced before assignment…This seems off to me as n is defined in the parent function. Appreciate the help.

Dan D.
  • 73,243
  • 15
  • 104
  • 123
na2561
  • 1
  • It looks like you are looking for a left fold applying the function f - [this might help](http://stackoverflow.com/questions/10366374/what-is-the-pythonic-equivalent-to-the-fold-function-from-functional-program)? – StuartLC Dec 24 '14 at 04:30

1 Answers1

1

Python, by default, allows access to variables from enclosing scopes, but does not allow you to set them—the minute you try to set one, Python considers it a local variable, and all accesses within that function to point to that local variable.

If you really want to, you can tell Python you really do want to set a non-local variable. To do this, use the nonlocal keyword. This works similarly to the global keyword:

def spam(var):
    def eggs():
        nonlocal var
        var += 1
        return var

    return eggs

In your case, though, this might be undesirable; you don’t want f to be invoked n times on the first invocation of the repeated-application function and no times at all on subsequent calls. For this reason, your first implementation is probably what you want.


As a general comment on your code, while it does not exhibit such interesting behavior, I would write this using a for loop:

def repeated(f, n):
    def value(x):
        for k in range(n):
            x = f(x)
        return x

    return value
icktoofay
  • 126,289
  • 21
  • 250
  • 231