Can Python's functool's reduce work with functions in the iterable?
<p>I'm trying to figure out how to return a function in Python. However, I don't know if the issue is with <code>reduce</code> or with my code. What I currently have is this:</p>

<h3>Code:</h3>

<pre><code>def combine(*args):
    from functools import reduce
    def closure(val):
        return reduce( (lambda x, f: f(x)), args, val)
    return closure


def first(array):
    return array[0]
def shift(array):
    return array[1:]
fifth = combine(first, shift, shift, shift, shift)
print(fifth([1,2,3,4,5,6,7,8,9]) # should return 5
</code></pre>

<p>However, I get the error message:</p>

<blockquote>
  <p>TypeError: 'int' object is not subscriptable</p>
</blockquote>

<p>What's causing this?</p>

<p>As it is defined in your question, <code>fifth(x)</code> is the same as:</p>

<pre><code>fifth(x) = shift(shift(shift(shift(first(x)))))
</code></pre>

<p>Now, if <code>x = [1,2,3,4,5,6,7,8,9]</code>, then</p>

<pre><code>first(x) = 1
</code></pre>

<p>But that means that</p>

<pre><code>shift(first(x)) = first(x)[1:] = 1[1:]
</code></pre>

<p>But as the error message tells us, <code>1</code> is not subscriptable.</p>

<hr>

<p>I assume what's really causing this is a misconception about the order <code>reduce</code> works. It works from left to right, so the leftmost function given is applied first (i.e., innermost):</p>

<pre><code>combine(a, b, c)(x) = c(b(a(x)))
</code></pre>

<p>If you instead wanted <code>a(b(c(x)))</code>, you would have to either pass them to <code>combine</code> in the reverse order, or modify your defintion of <code>combine</code> so that it reverses the order of the arguments for you:</p>

<pre><code>def combine(*args):
  from functools import reduce
  def closure(val):
    return reduce( (lambda x, f: f(x)), reversed(args), val)
  return closure
</code></pre>

python reduce