0

This simple piece of code works perfectly fine. What I'm about to ask is completely unnecessary; however, I'm trying to learn more about the functional programming approach to doing things.

p=[0, 1, 0, 0, 0]
pHit = 0.6
pMiss = 0.2
pExact = 0.8
pOvershoot = 0.1
pUndershoot = 0.1


def move(p, U):
    q = []
    # A functional approach could be used here as well, but focusing on the outer loop at the moment.
    for i in range(len(p)):
        s = pExact * p[(i-U) % len(p)]
        s = s + pOvershoot * p[(i-U-1) % len(p)]
        s = s + pUndershoot * p[(i-U+1) % len(p)]
        q.append(s)
    return q

#Instead of this for loop here, is there a more functional approach to doing the same thing?
for i in range(0,1000):
    p = move(p,1)

print move(p,1)

This person asked a similar question, but the difference is that he/she is applying the recursive function to the actual object being iterated over. Using recursion with map in python

My case seems different because I am not iterating over the object (the list "p") that I am applying the recursive function to. The "for loop" handles this pretty well because I want to do the recursive operation range(0,1000) times, but I've seen this issue come up a few times now, and I'm very interested in seeing the functional programming solution to this problem.

I've tried to use reduce() a few times, but I find it difficult to pass the output of the X iteration to the X+1 iteration.

3
  • The entire point of reduce is to pass the result of the x iteration to the x+1 iteration. I recommend looking over reductions again add they can be very useful. Commented Oct 23, 2016 at 13:26
  • Your completely right, but the examples I've seen of reduce() are iterating over the object(s) on which the operation is performed upon. I've seen a few combinations of reduce() & map(), but they didn't quite apply to this situation. Commented Oct 23, 2016 at 14:28
  • Reductions can be used even when you don't care about the items in the collection being iterated. Reducing over a range can be used to apply the reduction many times over and over again. Consider reduce(lambda acc n: return acc + 1), range(100), 0). Sorry if there are any syntax errors. It's been awhile since I've written Python. Commented Oct 23, 2016 at 14:32

1 Answer 1

3

To replace that loop at the bottom, you could do something like:

reduce(lambda q,_: move(q, 1), range(1000), p)

Notice how the values of the range are never even used, so they're indicated as being irrelevant using a _.

The reduction automatically passes the result of move to the next iteration.

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

7 Comments

needs a comma between q and n there
@ToreEschliman Whoops. Shows how long it's been since I've written Python :/. Thanks.
I think to indicate that n is never used you should replace it with _ (Not 100% sure if that convention is used in Python as well, I know it from other languages)
@UnholySheep Ya, that's how we do it in Clojure. I can't recall if a _ is a valid name in Python. I'll look into it. Thanks.
@Carcigenicate I think the critical piece I was missing was (like you pointed) on the last part of the documentation for reduce(): "If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty." In this example, is it fair to say that "p" is the "initializaer"?
|

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.