Lambda invalid syntax - python

This:
add = lambda x, y: x += y
Gives:
SyntaxError: invalid syntax
My task is to be able to mullitply or add every number between 1-513 with 1 function and 2 lambda functions. So if you have any suggestions that'll help.

As everybody said, you should put an expression not a statement in lambda body, Maybe this will help you:
from functools import reduce
add = lambda x,y: reduce(lambda i,j:i+j, range(x,y))
for mul:
mult = lambda x,y: reduce(lambda i,j:i*j, range(x,y))
or you can go without reduce, for add :
add = lambda x,y: sum(range(x,y))
also, you can use operator like this:
from operator import mul
from functools import reduce
mult = lambda x,y: reduce(mul, range(x,y), 1)

For continued multiplication, this works:
f = lambda n1, n2: n2 * (f(n1, n2-1) if n2 > 1 else 1)
print('f(1, 5) =', f(1, 5))
This output:
f(1, 5) = 120
(1 * 2 * 3 * 4 * 5 = 120)

Related

Composite functions in python - dual compose

I came across the following homework problem:
My code for this problem was marked wrong and when I viewed the suggested solution, I couldn't understand where I went wrong. I ran the codes of both functions in Python IDLE compiler only to see that both functions return the same output as seen below:
>>> def dual_function(f,g,n): #Suggested solution
def helper(x):
f1,g1 = f,g
if n%2==0:
f1,g1=g1,f1
for i in range(n):
x=f1(x)
f1,g1=g1,f1
return x
return helper
>>> def dual_function_two(f,g,n): #My solution
def helper(x):
if n%2==0:
for i in range (n):
if i%2==0:
x = g(x)
else:
x = f(x)
else:
for i in range(n):
if i%2==0:
x = f(x)
else:
x = g(x)
return x
return helper
>>> add1 = lambda x: x+1
>>> add2 = lambda x: x+2
>>> dual_function(add1,add2,4)(3)
9
>>> dual_function_two(add1,add2,4)(3)
9
>>>
I would appreciate it if someone could identify the mistake in my solution. Thank you.
The suggested solution is needlessly complex. Countless reassignments of variables and a loop are a recipe for a headache. Here's a simplified alternative -
def dual (f, g, n):
if n == 0:
return lambda x: x
else:
return lambda x: f(dual(g, f, n - 1)(x))
add1 = lambda x: 1 + x
add2 = lambda x: 2 + x
print(dual(add1,add2,4)(3))
# 9
# (1 + 2 + 1 + 2 + 3)
print(dual(add1,add2,9)(3))
# 16
# (1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 3)
print(dual(add1,add2,0)(3))
# 3
The reason this works is because in the recursive branch, we call dual with swapped arguments, dual(g,f,n-1). So f and g change places each time as n decrements down to 0, the base case, which returns the identity (no-op) function.
A slightly less readable version, but works identically -
def dual (f, g, n):
return lambda x: \
x if n == 0 else f(dual(g, f, n - 1)(x))

Sum of n lambda functions

I have a list of lambda functions. Lets say this one
l = [lambda x:x**i for i in range(n)]
For every n I need to be able to sum them so I'd have a function like this:
f = lambda x: x + x**2 + x**3 + ... + x**n
Is there any way?
Edit: I wasn't clear. I don't know anything about that functions.
Is this the solution you're looking for?
Python 3.x:
n = 5
g = lambda y: sum( f(y) for f in (lambda x: x**i for i in range(n)) )
print(g(5)) # 781
Python 2.x:
n = 5
g = lambda y: sum( f(y) for f in (lambda x: x**i for i in xrange(n)) )
print g(5) # 781
If you mean a finite sum, up to x**n, use the mathematical shortcut
f = lambda x: (x**(n+1) - 1) / (x - 1) if x != 1 else n
f = lambda x,n: sum( x**i for i in range(n) )
print f(3,4)
>> 40
The simplest way to do this is to avoid creating the list of lambda functions, and to instead sum over a single function. Assuming you've defined x and n, you can do:
f = lambda x, i: x**i
sum(f(x, i) for i in range(n))
In your original example, you have actually created a closure, so your lambda functions do not do what you think they do. Instead, they are all identical, since they all use the final value of i in the closure. That is certainly not what you intended.
n=5
xpower=[]
for i in range(n):
xpower.insert(i, i+1)
print(i,xpower)
f = lambda x, xpower: sum(x**xpower[i] for i in range(len(xpower)))
print("Example with n=5, x=2:"," ", f(2,xpower))

Python : addition of lambda defined functions

I am wondering if there is any way of adding to lambda functions at the function level.
import numpy as np
f = lambda x: np.sin(5*x)+3
g = lambda x: np.cos(3*x)**2+1
x = np.linspace(-3.14,3.14,1000)
h = f+g % is there any way to create this ?
h_of_x = h(x)
This would be very helpful.
If you're looking for symbolic mathematics, use sympy.
from sympy import *
x = symbols("x")
f = sin(5*x)+3
g = cos(3*x)**2+1
h = f + g
May be this
h = lambda x: f(x)+g(x)
You can create a function plus that takes two functions as input and return their sum:
def plus(f, g):
def h(x):
return f(x) + g(x)
return h
h = plus(lambda x: x * x, lambda x: x ** 3)
Example:
>>> h(2)
12
Defining plus can have advantages, like:
>>> f = lambda x: x * 2
>>> h = reduce(plus, [f, f, f, f]) # or h = reduce(plus, [f] * 4)
>>> h(2)
16

Limit to Number of Nested Function Calls in Python

Just a warning, this code is ugly. I know there are better ways of doing this but this is just an exercise.
I am poking around with the functional programming side of python, but I keep encountering an error when I try and nest a number of function calls:
LEN = 4
def calcentropy(i):
entropy[i] = -1 * reduce(lambda x,y: x+y, map(lambda x: x*np.log2(x), map(lambda x: x * (float(1)/float(NUM)), map(count, range(0,LEN)))))
map(calcentropy, range(0,LEN))
I get an error message stating that I have a mismatch between types; float and None for the last call to range(): TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'
When I do something like:
LEN = 4
def calcFreqs(i): do stuff to freqs
map(calcFreqs, range(0, LEN)
def calcentropy(i):
entropy[i] = -1 * reduce(lambda x,y: x+y, map(lambda x: x*np.log2(x), map(lambda x: x * (float(1)/float(NUM)), freqs))))
map(calcentropy, range(0,LEN))
I don't have any issues.
I think the problem is that LEN is no longer in scope of the call to range(). Is there a way I can fix this, or have I exceeded some sort of limit, and if so, what was it?
Sorry for not adding enough code, my mistake:
import numpy as np
LEN = 4
freqs = np.zeros(4 * LEN, dtype = np.float64)
sites = np.array([0,1,2,3,0,1,2,3,0,1,2,3], dtype = np.int8)
A = np.int8(0)
C = np.int8(1)
G = np.int8(2)
T = np.int8(3)
def count(i):
freqs[i * LEN + A] = E + reduce(lambda x,y:x+y, map(lambda x: 1 if x==A else 0, sites[i::LEN]))
freqs[i * LEN + C] = E + reduce(lambda x,y:x+y, map(lambda x: 1 if x==A else 0, sites[i::LEN]))
freqs[i * LEN + G] = E + reduce(lambda x,y:x+y, map(lambda x: 1 if x==A else 0, sites[i::LEN]))
freqs[i * LEN + T] = E + reduce(lambda x,y:x+y, map(lambda x: 1 if x==A else 0, sites[i::LEN]))
entropy = np.zeros(LEN, dtype = np.float64)
def calcentropy(i):
entropy[i] = -1 * reduce(lambda x,y: x+y, map(lambda x: x*np.log2(x), map(lambda x: x * (float(1)/float(NUM)), map(count, range(0,LEN)))))
map(calcentropy, range(0,LEN))
print entropy
info = map(lambda x: 2-x, entropy)
They issue you're having is that your count function doesn't return anything. In Python that is the same as returning None.
So when you run your long nested statement, you're getting a list of None values back from the innermost map call: map(count, range(0, LEN)). The first None value then causes an exception when it gets passed to the innermost lambda expression and you try to multiply it by a float.
So, you either need to use something else as the innermost value for your big nested structure, or you need to fix up count to return something. It's not clear to me what you're intending to iterate over, so I can't really offer a solid suggestion. Perhaps freqs?
Also, I suggest avoiding map when you simply want to run a function a bunch of times but don't care about the results. Instead, write an explicit for loop. This matters in Python 3, where map returns a generator (which doesn't do anything until you iterate over it).

how to print lambda expression

I have two (many) lambdas:
myFoo = lambda x,y: x + y
mySpecFoo = lambda x: myFoo(x, 1)
I want to print resulting expression for mySpecFoo. smth like
x = var('x')
print(mySpecFoo(x))
and I want to see in output:
lambda x: x + 1
Do you know how to do this?
Thank you!
This is called "symbolic evaluation", and you need some external library to do this, for example SymPy:
>>> import sympy
>>> myFoo = lambda x,y: x + y
>>> mySpecFoo = lambda x: myFoo(x, 1)
>>> x = sympy.var("x")
>>> print mySpecFoo(x)
1 + x

Categories

Resources