Python lambda function outputs function_main messages instead of numbers? - python

I am trying to generate a scatter plot with x in range (0,17) and y = 1/(x**2+1). Here's the code that I use to generate the lambda function for y:
y = [lambda x:1/(x**2+1) for x in range(17)]
y
Apparently it shows this output 17 times:
<function __main__.<listcomp>.<lambda>(x)>,
<function __main__.<listcomp>.<lambda>(x)>,
<function __main__.<listcomp>.<lambda>(x)>,
<function __main__.<listcomp>.<lambda>(x)>,
What did I do wrong with the code above? Thanks!

You're not calling the function in the loop.
You can either do
f = lambda x: 1 / (x ** 2 + 1)
y = [f(x) for x in range(17)]
or forgo the lambda and just
y = [1 / (x ** 2 + 1) for x in range(17)]

If you indeed wanted to use lambda inside list comp, you should have done this:
>>> y = [(lambda x:1/(x**2+1))(x) for x in range(17)]
>>> y
[1.0, 0.5, 0.2, 0.1, 0.058823529411764705, 0.038461538461538464, 0.02702702702702703, 0.02, 0.015384615384615385, 0.012195121951219513, 0.009900990099009901, 0.00819672131147541, 0.006896551724137931, 0.0058823529411764705, 0.005076142131979695, 0.004424778761061947, 0.0038910505836575876]
Here the x with the lambda has nothing to do with the x being iterated, it is the parameter of the lambda function. The x in the function call outside the parentheses that encloses lambda is the value you are passing to the function.
This was just for explanation purposes, it does not make any sense to write programs this way, the accepted answer is the way you should go.
However, if you want to go crazy with lambda, you can watch David Baezley's talk on lambda calculus with python.

Related

Python for loop in the lambda to create 100 x[i]

In my code I need to create a lambda to realize ax1+~~~~~~zx100, in which a,~~z, are known parameters. I need to put a for loop inside a lambda expression, to realize such function:
x = lambda x: 5*x[0]+20*x[1]+~~~~~~21*x[99]
I wonder, if number of my variables are 1 million, how to realize it? I do not know how to make it happen. Please help, thank you so much!
If you need to pass both the parameters, you could make a lambda to accept both lists, like so:
a = [1,2,3,4,5]
x = [6,7,8,9,0]
sum_of_products = lambda _a,_x: sum(y*z for y, z in zip(_a, _x))
print(sum_of_products(a,x))
80
Alternatively, and preferably you can also just define a normal function for this as well, and achieve the same results.:
def sum_of_products(a, x):
return sum(y*z for y, z in zip(a, x))
Once you've written the function, you can also pass it around just like a lambda, so if you were going to assign it to a variable to begin with, it might be easier to read if you just def your function in the normal way.
a = [1,2,3,4,5]
x = [6,7,8,9,0]
def sum_of_products(_a, _x):
return sum(y*z for y, z in zip(_a, _x))
my_function = sum_of_products
print(my_function(a, x))
80
Try something like this:
lambda x: sum(a * b for a, b in zip(x, [5, 20, ..., 21]))

How does lambda inside lambda function work?

When I try to print and see what each function does, I'm able to call only the h function. All others return functions.
Also, can anybody tell me why this code prints 13 and what is happening?
two_to_one = lambda g: (lambda y: g(y,y))`
one_to_two = lambda f: (lambda x, y: f(x) + f(y))
h = one_to_two(two_to_one(lambda x, y: x*y))
print(h(3,2))
That was quite a mind bender!
So let's just break the logic bit by bit. We'll start from h, it is essentially
h = lambda x, y : x*x + y*y
h(3,2) # output is 13
Now, we'll be good programmers and look for repetition. x*x and y*y are essentially the same thing. Why not have a lambda that does that?
a = lambda x: x*x
h = lambda x,y: a(x) + a(y)
h(3,2)
Good, but I want the caller to decide whether to do x*x or x**x or x+x. Everytime I do that I dont want to change a. So I instead pass a lambda to a with whatever operation I want to perform
# a is just a delegator now. It just calls the lambda that it is "initialized" with passing the values twice
a = lambda lambdaIAmPassing: (lambda someValue: lambdaIAmPassing(someValue, someValue))
# lets pass a multiplication lambda
mul_a = a(lambda x,y: x*y)
# lets pass a addition doing lambda
add_a = a(lambda x,y: x+y)
h = mul_a(3) + mul_a(2)
print h #output is 13
h = add_a(3) + add_a(2)
print h # output is 10
Is this clear? You would have realized now that a is in fact the lambda two_to_one in your question
Now the final step.Do you see any other repetition in the code? we are calling mul_a twice and add_a twice. So to avoid this we define a lambda that calls whatever function is passed to it twice - once per parameter - and adds up the values
# Lambda that adds up the result of the function call
lambda_adder = lambda f: (lambda value1, value2: f(value1) + f(value2))
"Initialize" this lambda with mul_a
h = lambda_adder(mul_a)
h(3,2) # output is 13
Hence we end up with the code in your question
two_to_one = lambda g: (lambda y: g(y,y))
This equals a function which calls a function g, passing it two variables, both y. In this case, g is
lambda x, y: x*y
because that is the argument passed to two_to_one on the third line (h's assignment).
one_to_two = lambda f: (lambda x, y: f(x) + f(y))
This equals a function which returns the sum of two calls to the function f, passing the values x and y. In this case, f is the two_to_one function.
Breaking it down:
first = lambda x, y: x*y
second = lambda y: first(y,y)
third = lambda x, y: second(x) + second(y)
simplifies to:
second = lambda y: y * y
third = lambda x, y: second(x) + second(y)
simplifies to:
third = lambda x, y: x * x + y * y
So, what the code is doing is returning the sum of the squares of the arguments. In this case, they are 3 and 2.
I hope it will be relatively easy to follow.
two_to_one = lambda g: (lambda y: g(y,y))
two_to_one is a function, with an input of a function (g: a function with an input of two parameters (as seen in g(y,y)), and output of a function (with 1 input y, and output of g(y,y)). Meaning it is a function of functions. So when giving two_to_one a two parameter function g, you get back a function, that takes 1 number and outputs g(y,y).
e.g:
two_to_one(lambda x,y:x+y)(3)
6
We gave two_to_one a function that gets two numbers and output their sum, lambda x,y:x+y, and we got back a function that takes 1 number and output its sum with itself two_to_one(lambda x,y:x+y). So with an input of 3 it outputs 6.
Second line is similiar:
one_to_two = lambda f: (lambda x, y: f(x) + f(y))
Take a function f (of 1 parameter - due to f(x)), and give back a function, that gets two parameters (numbers probably) x,y and outputs f(x) + f(y).
Now, for the 13 output - working from inner to outer:
h = one_to_two(two_to_one(lambda x, y: x*y))
lambda x, y: x*y two parameter input - output of multiplication. This is the input of two_to_one so (remember what was written earlier) two_to_one(lambda x, y: x*y) is a function that gets 1 number, and returns it squared. And finally, feeding this function to one_to_two gives a function that gets two numbers (those x,y frim before) and returns their sum of squares.
In total h(3,2) gives 3**2+2**2=13.

Why do I need brackets around lambda functions when assigning them to variables?

I've just stumbled about some unexpected behavior in Python in the below code snippet
b = False
func_1 = lambda x,y:set([x]) == y if b else lambda x,y: x in y
func_2 = None
if not b:
func_2 = lambda x,y : x in y
else:
func_2 = lambda x,y:set([x]) == y
print(func_1("Hello", set(["Hello", "World"])))
print(func_2("Hello", set(["Hello", "World"])))
The output is
<function <lambda>.<locals>.<lambda> at 0x7f7e5eeed048>
True
However, when adding brackets around the lambdas everything works as expected:
func_1 = (lambda x,y:set([x]) == y) if b else (lambda x,y: x in y)
# ...
The output then is
True
True
Why do I need those brackets? I thought the initial expression was equivalent to the long if-else construct.
It's just standard precedence rules. Your first expression is being parsed as:
lambda x,y:set([x]) == (y if b else lambda x,y: x in y)
So you need to add the parentheses to create the correct precedence.

list of lambdas in python [duplicate]

This question already has answers here:
Creating functions (or lambdas) in a loop (or comprehension)
(6 answers)
Closed 6 months ago.
I have seen this question, but i still cannot get why such simple example does not work:
mylist = ["alice", "bob", "greta"]
funcdict = dict(((y, lambda x: x==str(y)) for y in mylist))
funcdict['alice']("greta")
#True
funcdict['alice']("alice")
#False
funcdict['greta']("greta")
#True
How is it different from:
[(y, y) for y in mylist]
Why y is not evalueated within each step of iteration?
The y in the body of the lambda expression is just a name, unrelated to the y you use to iterate over mylist. As a free variable, a value of y is not found until you actually call the function, at which time it uses whatever value for y is in the calling scope.
To actually force y to have a value at definition time, you need to make it local to the body via an argument:
dict((y, lambda x, y=z: x == str(y)) for z in mylist)
((y, lambda x: x==str(y)) for y in mylist)
y inside the lambda is not bound at the time of the genration expression defined, but it's bound when it's called; When it's called, iteration is already done, so y references the last item greta.
One way to work around this is to use keyword argument, which is evaluated when the function/lambda is defined:
funcdict = dict((y, lambda x, y=y: x == y) for y in mylist)
funcdict = {y: lambda x, y=y: x == y for y in mylist} # dict-comprehension
or you can use partial:
funcdict = {y: partial(operator.eq, y) for y in mylist}
y is evaluated while the mylist is iterated.

How to define a mathematical function in SymPy?

I've been trying this now for hours. I think I don't understand a basic concept, that's why I couldn't answer this question to myself so far.
What I'm trying is to implement a simple mathematical function, like this:
f(x) = x**2 + 1
After that I want to derive that function.
I've defined the symbol and function with:
x = sympy.Symbol('x')
f = sympy.Function('f')(x)
Now I'm struggling with defining the equation to this function f(x). Something like f.exp("x**2 + 1") is not working.
I also wonder how I could get a print out to the console of this function after it's finally defined.
sympy.Function is for undefined functions. Like if f = Function('f') then f(x) remains unevaluated in expressions.
If you want an actual function (like if you do f(1) it evaluates x**2 + 1 at x=1, you can use a Python function
def f(x):
return x**2 + 1
Then f(Symbol('x')) will give a symbolic x**2 + 1 and f(1) will give 2.
Or you can assign the expression to a variable
f = x**2 + 1
and use that. If you want to substitute x for a value, use subs, like
f.subs(x, 1)
Here's your solution:
>>> import sympy
>>> x = sympy.symbols('x')
>>> f = x**2 + 1
>>> sympy.diff(f, x)
2*x
Another possibility (isympy command prompt):
>>> type(x)
<class 'sympy.core.symbol.Symbol'>
>>> f = Lambda(x, x**2)
>>> f
2
x ↦ x
>>> f(3)
9
Calculating the derivative works like that:
>>> g = Lambda(x, diff(f(x), x))
>>> g
x ↦ 2x
>>> g(3)
6
Have a look to:
Sympy how to define variables for functions, integrals and polynomials
You can define it according to ways:
a python function with def as describe above
a python expression g=x**2 + 1
I recommended :
first, define a symbolic variable
x = sympy.symbols('x')
second, define a symbolic function
f = sympy.Function('f')(x)
define a formula
f = x**x+1
if you have so many variable can use this function
def symbols_builder(arg):
globals()[arg]=sp.symbols(str(arg))
if you have so many functions can use this function
def func_build(name, *args):
globals()[name]=sp.Function(str(name))(args)

Categories