if and else in python lambda expression - python

Please help me to understand how this works. Output is 4
a=4
b=7
x=lambda: a if 1 else b
lambda x: 'big' if x > 100 else 'small'
print(x())

First, let's remove this line as it doesn't do anything:
lambda x: 'big' if x > 100 else 'small'
This lambda expression is defined but never called. The fact that it's argument is also called x has nothing to do with the rest of the code.
Let's look at what remains:
a = 4
b = 7
x = lambda: a if 1 else b
print(x())
Here x becomes a function as it contains code. The lambda form can only contain expressions, not statements, so it has to use the expression form of if which is backward looking:
true-result if condition else false-result
In this case the condition is 1, which is always true, so the result of the function x() is always the value of a, assigned to 4 earlier in the code. Effectively, x() acts like:
def x():
return a
Understanding the differences between expressions and statements is key to understanding code like this.

Your x is always equals to 4, as it takes no arguments and if 1 is always True.
Then you have lambda expression that's not assigned to any variable, neither used elsewhere.
Eventualy, you print out x, which is always 4 as I said above.
P.S. I strongly suggest you to read Using lambda Functions from Dive into Python

Let me translate that for you.
You assign to x a lambda function with no arguments. Because 1 always evaluates as true, you always return the externally defined variable a, which evaluates as 4.
Then, you create a lambda function with one argument x, which you don't assign to a variable/access name, so it is lost forever.
Then, you call function x, which always returns a. Output is 4.

Related

I don't understand how these recursive calls could finish

Here is my simple Python function:
def f(b):
return b and f(b)
To me this must be an infinite loop, no matter the value of b, because b is always the same. But:
With f(True) I get an overflow, which is what I expected
When I run f(False) I get False!
I'm very curious about that.
Recursion stops when b is falsey, i.e. False (or an empty string, or zero).
In some more detail,
x and y
does not evaluate y if x is False (or, as explicated above, another value which is interpreted as that when converted into a bool value, which Python calls "falsey"), as it is then impossible for y to affect the outcome of the expression. This is often called "short-circuiting".

How to commute two operators in python?

Let's say I have operator A and operator B which act on f(x) = 2x for example. How do I create a function that says whether A(B(f(x))) == B(A(f(x))) in python?
Here is my attempt:
#Commutation: Creating a function that checks whether operators A and B commutate on some dummy function f(x) = 2*x
#[A,B](2x) =?= 0
def commutate(A,B):
f = lambda x: 2*x
if lambda x: A(B(f)) - B(A(f)) == 0:
print('A and B commute!')
else:
print('A and B do not commute!')
A = lambda x: f(x)**2
B = lambda x: np.log(f(x))
commutate(A,B)
The issue is that I'm always getting that the operators A and B commute, even when giving Operators that don't. I suspect this might have to do with the fact that I can't Define operators like that in python?
In general, it is not possible, based on Rice theorem. Because you desire to check a non-trivial property for two pieces of code, i.e., the property is commutativeness and piece of code here means functions. Hence, it proves that deciding that "any given f and g functions are commutative" is undecidable. Therefore, you can't write such a function to check the commutativeness for two functions.
In your code you have the line
if lambda x: A(B(f)) - B(A(f)) == 0:
In this line you are generating a lambda that is calling the operators on the address of f rather than a result of calling f. Also, you are not calling the lambda that you define in the if statement, so you are checking if the address of the lambda function is True/False which is not what you are looking for.
Lambdas are just functions, but you could test if the operators are commutative on a specific value:
def commutate(A, B, value):
f = lambda x: 2 * x
if A(B(f(value))) == B(A(f(value))):
print(f"A and B commute on value {value}!")
else:
print(f"A and B do not commute on value {value}!")

Control Structures and Functions inside lambda

Create a lambda function greater, which takes two arguments x and y and return x if x>y otherwise y. input value is (9,3)
greater= lambda a,b:a>b
if a>b:
print(a)
else:
return b
print(greater(a,b))
File "/code/source.py3", line 11
return b
^
SyntaxError: 'return' outside function
Even I am getting error in return statement.
I have to only get the output as value but I am getting value with True.
Use if - else in lambda:
greater = lambda a, b: a if a > b else b
and call it as:
greater(9, 13)
Problems with your code:
Your lambda function just compares two variables and returns a True / False.
You used return outside a function which is not allowed. (Btw, there is no need of explicit if - else outside lambda when you can do within).
You don't return from a lambda function.
greater = lambda a,b: a if a > b else b
print(greater(3,4))
You can use ternary operators (a if a > b else c) in lambdas but control structures require the def keyword
Also, there is no return in a lambda function
Use a ternary if in your lambda:
greater = lambda x,y: x if x>y else y
greater(1,3) # 3
greater(4,3) # 4
Small anonymous functions can be created with the lambda keyword. Lambda functions can be used wherever function objects are required. They are syntactically restricted to a single expression.
Read more.
Solution without using ternary expression:
greater = lambda a, b: (a, b)[a<b]
a<b returns the boolean value False if a is greater than, or equal to, b, and True if a is smaller than b. We use the boolean value (basically representing 0 or 1) as an index to the tuple (a, b) to return our desired result.

Python: how to make functions in arrays

I am trying to make my code a bit more dynamic and smaller so I am trying to use some arrays, but I need to put a function in a array. I heard of the lambda but the problem is that it doesnt need to return any value but it does need to set a value. this is what I tried but didn't work:
variableArray = [lambda: value = '2' if variable == 1 else None,lambda: value = '3' if variable == 1 else None]
for k in range(len(variableArray)):
print(variableArray[k](2))
but I can't set a value with this methode and I wasn't abled to find any other methodes. so are there any other methodes that would work with what I am trying to do?
Python distinguish between expressions and statements (and here compound statements). Expressions can not contain any statements. An assignment is a statement. lambdas are expressions, hence there's no way to use a lambda with that syntax.
However using normal defs wouldn't change much:
def function():
value = '2' if variable == 1 else None
Here the function is creating a new local variable value, assigning it the its value and then removing it. If you want to modify a non-local variable you must declare it as global:
def function():
global value
value = '2' if variable == 1 else None
Note that you can put functions defined with defs into a list:
some_list = [function, #other functions]
However you should try to avoid using global variables as much as you can.
You should prefer function parameters and return values to communicate between the function and the rest of the program.
In particular you probably wanted to write functions such as:
variableArray = [lambda arg: '2' if arg == 1 else None, lambda arg: '3' if arg == 1 else None]
You can then do:
for func in variableArray:
value = func(2)
This will have the same effect as your code.
Note that the lambdas should have a parameter, otherwise calling them with the (2) will raise an error.
Functions in arrays is possible. But you can't put assignments in lambdas. And your lambda isn't taking any arguments, despite passing 2 into them.
And for k in range(len(variableArray)): is wasteful bad form. Try just:
for k in variableArray:
print(k(2))
As for the functions, maybe you want this?
variableArray = [lambda x: '2' if x == 1 else None, lambda x: '3' if x == 1 else None]
It's not entirely clear what you need, but maybe this is closer to what you're after.
If you want to get a list of values from the list of functions, passing a single argument into the function-list, try this:
functions = [lambda x: '2' if x == 1 else None, lambda x: '3' if x == 1 else None]
values = [function(2) for function in functions]

Python: Why does a lambda define the variable in an inline if?

Toying around with lambdas in Python I discovered that the following code is legal in Python 2.7.3 and returns the lambda:
x = lambda: 1 if x else 2
Why does the lambda define x when used in this way?
Edit: Python syntax is apparently too hard for me, see the accepted answer…
Why does the lambda define x when used in this way?
It doesn't. The assignment x = [any expression] defines x to be [any expression]. In this case, the expression is lambda: 1 if x else 2, which evaluates to a function object without arguments, and it is that which x holds.

Categories