Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community!

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Functional Python The Lambda Lambada Currying

Help with the last return lambda inside curried_f

Hi! I understand that this first part of the function in the video comes into effect for some combinations of arguments (if y and z passed, if only z is not passed) when curried_f is called:

def curried_f(x, y=None, z=None):
    def f(x, y, z):
        return x**3 + y**2 + z

    if y is not None and z is not None:
        return f(x, y, z)
    if y is not None:
        return lambda z: f(x, y, z)

I also assume that the next part takes care of the other possible combinations (if neither z nor y are passed, if y is not passed):

    return lambda y, z=None: (
        f(x, y, z) if (y is not None and z is not None)
        else (lambda z: f(x, y, z)))

However, what happens in there doesn't seem to translate into that. The "if (y is not None and z is not None)" and "(lambda z: f(x, y, z))" both look like they refer to combinations of arguments already tackled in the first part (respectively: if y and z passed, if only z is not passed). How does that last part work to achieve "if neither z nor y are passed, if y is not passed"?

2 Answers

Steven Parker
Steven Parker
228,001 Points

You're confusing the conditions of the returned lambda with the conditions of curried_f itself.

That final "return" gives you another function (a lambda) that will give you the result if called with 2 arguments, but give you yet another lambda if called with only one.

Consider what happens in each of the 4 possible usage cases to get a final value:

curried_f(2, 3, 4))  # first return
curried_f(2, 3)(4))  # second return
curried_f(2)(3, 4))  # third return, then first case
curried_f(2)(3)(4))  # third return, then second case

I think I get it. So that last return is for people who only passed in X. It would say something like: "I transform the caller into a function that requires 'Y' and accepts 'Z', which simply returns the final result if both are given. If this is not the case, and I only get 'Y', I change the caller to a function that needs 'Z'." Thanks!