Reputation: 35
EXAMPLE: Why dictuse1 return value but dictuse2 return address as specified below
def dictuse1(operator,x,y):
return{
'add':lambda:x + y,
'sub':lambda:x - y,
'mul':lambda:x * y,
'div':lambda:x / y,
}.get(operator,lambda:None)()
def dictuse2(operator,x,y):
return{
'add':lambda:x + y,
'sub':lambda:x - y,
'mul':lambda:x * y,
'div':lambda:x / y,
}.get(operator,lambda:None) #No parentheses here compared to previous function
d = dictuse1('add',8,9)
print(d) #return 17
a = dictuse2('a',5,4)
print(a) #returns:<function dictuse.<locals>.<lambda> at 0x7f30d23f3ea0>
Upvotes: 2
Views: 173
Reputation: 6709
Try splitting such one-liners on some meaningful parts.
def dictuse1(operator, x, y):
# Stores mapping from operator names (strings)
# to op implementations (functions == lambdas)
optable = {
'add': lambda: x + y,
'sub': lambda: x - y,
'mul': lambda: x * y,
'div': lambda: x / y,
}
# Define a default op
noop = lambda: None
# Take the function by op name
op = optable.get(operator, noop)
# Exectute it and return a returning value of that function.
return op() # remove () and you have a dictuse2 here.
The only difference between dictuse1
and dictuse2
that the last one returns the function instead of the result of the invocation of that function.
Upvotes: 2
Reputation: 365925
The parentheses have nothing to do with the return
; they’re there to call a function, the same way you always call a function.
Let’s break this down into a more readable form:
function_table = {
'add': lambda: x + y,
'sub': lambda: x - y,
'mul': lambda: x * y,
'div': lambda: x / y,
}
So far, so good: this is just a dictionary that maps strings to functions, so you can look the functions up by name.
default_function = lambda: None
This is just a function that you can call and get back None
.
function = function_table.get(operator, default_function)
This is just looking up a value in a dict. d.get(key, default)
gives you d[key]
if there is a value with that key, or default
if there isn’t.
So, now function
is that add
function lambda: x+y
, or the default lambda: None
, or any of the other three , but whichever one it is, it’s a function that takes no parameters. So we can call It. This is where the parentheses come in:
value = function()
And now we just return that value:
return value
If you left the parentheses off, you wouldn’t be calling the function and returning the value it gives you, you’d just be returning it. So, instead of getting back 5
or None
, you’d get back a function object. If you try to print that out, maybe it’ll say something like <function '<lambda>' at 0x12345788>
, but it doesn’t really matter what it says; all it’s telling you is that the thing you’re printing is some function, and it has no name because you defined it with lambda
instead of def
.
Upvotes: 4
Reputation: 2130
Because get
method on dictionary return a default value if the key you are looking for is not in the dictionary, When you passed a
which is not in the dictionary it returned lambda:None
which is a anonymous function and to execute the function you have to call with paranthesis
Upvotes: 0
Reputation: 44878
Because in Python everything is an object. This includes integers, floating-point numbers, strings, instances of other classes, classes themselves and functions.
The first function retrieves a function from the dictionary or uses the default value and calls it, returning the result of the call (a number in your case).
The second one returns the function itself.
The parentheses are notation for function call: (lambda x, y: x + y)(1, 2)
, for example, calls the function and returns 1 + 2 == 3
. If you remove the parentheses, you'll get a function object.
Upvotes: 1