Python Forum

Full Version: what "return" means?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
def myfunc(n):
  return lambda a : a * n

mydoubler = myfunc(2)

print(mydoubler(11))
return passes a value back to a calling function or method
Example:
def aaa():
   return 456

def bbb()
   print(aaa())

bbb()
All functions return a value when called.

If a return statement is followed by an expression list, that expression list is evaluated and the value is returned:

>>> def greater_than_1(n):
... return n > 1
...
>>> print(greater_than_1(1))
False
>>> print(greater_than_1(2))
True
(Oct-09-2019, 12:50 PM)prih_yah Wrote: [ -> ]All functions return a value when called.

Except for void functions, which do not return anything.
If interested in 'return' statement one can refer to Python built-in help:

>>> help('return')
Quote:The "return" statement
**********************

return_stmt ::= "return" [expression_list]

"return" may only occur syntactically nested in a function definition,
not within a nested class definition.

If an expression list is present, it is evaluated, else "None" is
substituted.

"return" leaves the current function call with the expression list (or
"None") as return value.

When "return" passes control out of a "try" statement with a "finally"
clause, that "finally" clause is executed before really leaving the
function.

In a generator function, the "return" statement indicates that the
generator is done and will cause "StopIteration" to be raised. The
returned value (if any) is used as an argument to construct
"StopIteration" and becomes the "StopIteration.value" attribute.

In an asynchronous generator function, an empty "return" statement
indicates that the asynchronous generator is done and will cause
"StopAsyncIteration" to be raised. A non-empty "return" statement is
a syntax error in an asynchronous generator function.

Related help topics: FUNCTIONS
(Oct-09-2019, 01:10 PM)JTHilliard Wrote: [ -> ]Except for void functions, which do not return anything.

There are no real void functions in Python, every function returns a value. If the function ends without an explicit return statement, the None singleton is returned. It may be None, but it is still a value.
The really cool thing about the example OP gives is that the method returns a function. This points out that you can return any object, even complex objects like functions.
You are returning a function, a lambda is an anonymous function. Functions in Python are objects and can be passed around, mydoubler is now a function and can be called. What is hapening is that each time you call myfunc with a different integer you can get back a unique function that returns that value * its argument. You could say this is like a factory for creating functions on the fly that you don't have to type out manually. This is the best explanation I can think of that would hopefully help. I would lookup How to use Python Lambda Functions There are a lot of resources that can explain both lambdas and functions that return functions. That's where I would start looking.
def myfunc(n):
    return lambda a : a * n
is similar to this:
def myfunc(n):
    def inner(a):
        return a * n
    return inner
In both cases the function myfunc returns a function.
The lambda expression is an anonymous function. In both cases the function myfunc is a closure.
This means inside the function is another one, which has access to the stack of the parant function.

Calling this function looks strange:
n = 10
a = 20
result = myfunc(n)(a)
print(result)
You can bring this back a normal form:
def myfunc(n, a):
    return a * n
Calling it:
result = myfunc(10,20)
Closures are used for decorators and functional style. For example inside the operator module are this kind of closures available.

import operator

# list with dicts
mylist1 = [dict(value=10, name='c'), dict(value=20, name='b'), dict(value=30, name='a')]
# we want to sort by name, no problem:
by_name = sorted(mylist1, key=operator.itemgetter('name'))
by_value = sorted(mylist1, key=operator.itemgetter('value'))
The sorted function uses the key to sort. It must be a callable and for each item in the list, the callable is called with. The callable should return something, that can be used for sorting. For example it may return str, then it's sorted lexically or it returns numbers or tuples with numbers. Mostly you see in examples for sorting the lambda expression.

In tutorials about sorting, you see often this:
by_name = sorted(mylist1, key=lambda x: x['name'])
by_value = sorted(mylist1, key=lambda x: x['value'])
Another thing you have to know, that functions return implicit None.

def foo():
    print('Hello foo')

ret_val = foo()
print(f"Return value of foo is: {ret_val}\nIt's type is: {type(ret_val)}")
Output:
Hello foo Return value of foo is: None It's type is: <class 'NoneType'>
(Oct-10-2019, 07:05 AM)DeaD_EyE Wrote: [ -> ]
def foo():
    print('Hello foo')

ret_val = foo()
print(f"Return value of foo is: {ret_val}\nIt's type is: {type(ret_val)}")
Output:
Hello foo Return value of foo is: None It's type is: <class 'NoneType'>

Big Grin I was just thinking that for newbies like myself, the first times I saw these foo and bar thingies, they completely confused me. So I posted an explanation that suddenly disappeared, but it seems that it has been placed in a more appropriate place:

https://python-forum.io/Thread-spam-eggs...or-newbies

All the best,