Order should be as specified! error [duplicate] - python

This question already has answers here:
What's the best way to return multiple values from a function? [duplicate]
(6 answers)
Closed 6 years ago.
def compose(f,g):
return lambda f: f + 1
return lambda g: g
how can I specify the order of the return statements
These are the test cases;
add1 = lambda a: a+1
this = lambda a: a
test.expect( compose(add1,this)(0) == 1 )

def compose(f1, g1):
# do something
return lambda f:f+1, lambda g:g
will return a tuple of two functions.
You can get the individual functions like this:
func1, func2 = compose(a,b)

You cannot have two return statements in a function. Once the first one is called, the second will not be reached because the function has already returned. You could, however, use a tuple to organize the output, which would look like this.
def compose(f,g):
return (lambda f: f + 1, lambda g: g)
Be careful though, because this will return the actual lambdas as the below example shows:
In [7]: def func(f, g):
...: return (lambda f: f + 1, lambda g: g)
...:
In [8]: func(0, 0)
Out[8]: (<function __main__.<lambda>>, <function __main__.<lambda>>)
Notice the types shows by line out[8]. This means that what ever variables that the function returns to will be the actual functions, not a number. To return a number, don't use lambdas, just calculate the numbers normally.
It's also worth noting, that the parameters have no effect on this function.

def compose(f,g):
return lambda f: f + 1,lambda g: g
print compose(f,g)[0]
print compose(f,g)[1]

Related

Create a new function from a list of functions [duplicate]

This question already has answers here:
Apply a list of Python functions in order elegantly
(2 answers)
Closed 2 years ago.
Consider a few simple functions:
add2 = lambda x: x+2
add3 = lambda x: x+3
add4 = lambda x: x+4
And having them stored in a list:
funcs = [add2, add3, add4]
Is there a way, how to create a new function, which applies all the given ones?
Not working solution:
f = funcs[0]
for g in funcs[1:]:
f = lambda x: g(f(x))
This does not work, since after trying to call the create function f(0), I get RecursionError: maximum recursion depth exceeded, which I don't completely understand.
The solution for the question Apply a list of Python functions in order elegantly does not work for my problem.
I don't want to get to the result (yet), I want to construct a new function
from functools import reduce
result = reduce(lambda res, f: f(res), funcs, val)
However, it should work with a combination of partial.
Working solution with functools:
import functools
f = functools.partial(functools.reduce, lambda res, f: f(res), funcs)
Working solution (without lambdas):
def _inner(x):
for f in funcs:
x = f(x)
return x
Calling _inner(0) returns correctly 9.

how to build generic sum of python function results

I would like to build the sum of functions in python. However, I don't know upfront the length of the sum. All functions are of similar type, i.e. having one input and same output type. For two something like this would work
In [180]: def H(f, g):
...: def _h(x):
...: return f(x) + g(x)
...: return _h
However, I would like to have something which is generic in the sense that I could write H(*args) and it returns me the sum of all function in args (also working for just one).
Am I correct that this is the only way to build sum of functions? I can't write something like h = f+g for two function ?
It is probably easier to write something that is extendable. And you should use the built-in function sum to do the actual summing. This returns a generator that applies each function to the input x:
def map_funcs(x, *funcs):
return (f(x) for f in funcs)
funcs = lambda x: x + 1, lambda x: x**2
x = 10
print(sum(map_funcs(x, *funcs)))
If you want to you can also make it a wrapper which returns something callable, similar to what you've already got:
def map_funcs(*funcs):
def wrapper(x):
return (f(x) for f in funcs)
return wrapper
funcs = lambda x: x + 1, lambda x: x**2
x = 10
print(sum(map_funcs(*funcs)(x)))
# 111
Yes, it's possible. You have to use the sum() builtin function that return the sum of all values in the given list. Before that, you of course have to compute the list of all the functions givent to H() run with the correct parameter:
def power_two(x):
return x**2
def plus_20(x):
return x + 20
def H(*args):
def _h(x):
_results = [f(x) for f in args]
return sum(_results)
return _h
if __name__ == '__main__':
the_func = H(power_two, plus_20)
final_result = the_func(2)
print("(2^2) + (2+20) = %s" % the_func(2))
print("(3^2) + (3+20) = %s" % the_func(3))
Returns:
(2^2) + (2+20) = 26
(3^2) + (3+20) = 32
Try this:-
def H(*args):
def _h(x):
for func in args:
z += func(x)
return z
return _h
Just loop around the functional arguments and then sum it. I guess simple?
I hope it helps!

accessing lambda value passed to function python

I am trying to access the value of the lambda functions when i pass the value on the same line as the function is called. the only way i can get the value is to return(f). Is there any way to access the value before this and compare it to other values?
def func(f):
return(f)
func(lambda x: x*2)(3)
6
You can't. The (3) is passed to what func() returns, so the func can't access it. This is what happens:
def func(f):
return f # parenthesis unnecessary.
func(lambda x: x*2)(3)
Which, when the lambda function is returned, turns to:
(lambda x: x*2)(3)
Which is:
3*2 # 6
This way, you see that the function does not interact with the argument passed to the lambda. You can't access it directly.
I'm still not sure about your use case - are you trying to do something like this?
def func(f, *args):
result = f(*args)
# Do some simple comparison with the result of the lambda
myValue = 8
msg = "8 > %d" if 8>result else "8 <= %d"
return msg % result
print(func(lambda x:x*2, 3)) # prints 8 > 6
print(func(lambda x:x*2, 5)) # prints 8 <= 10
print(func(lambda x:x**2, 3)) # prints 8 <= 9
As you can see, doing that requires changing func to accept the parameter for the lambda along with the lambda itself.

Can a decorator be working with a lambda expression at runtime? [duplicate]

This question already has answers here:
How to apply decorators to lambdas?
(3 answers)
Closed 6 years ago.
def attrs(**kwds):
def decorate(f):
for k in kwds:
setattr(f, k, kwds[k])
return f
return decorate
#attrs(argument_types=(int, int,), returns=int)
def add(a, b):
return a + b
Here I need the add() can be with the ability to show its acceptable parameter type.
but can I do something like this in runtime?
ladd=[]
for x in range(0,10):
#attrs(argument_types=int, returns=int,default_parameter1 = x)
exp = lambda : add(a,x)
ladd.append(exp)
or
ladd=[]
for x in range(0,10):
#attrs(argument_types=int, returns=int,default_parameter1 = x)
addx = functools.partial(add, 2)
ladd.append(addx)
I need those function can be generated runtime with the "decoratored" parameter bind either
Well, here is the error information, I think above code can not work, but I never tried to paste it to python to test it...
>>> ladd=[]
>>> for x in range(0,10):
... #attrs(argument_types=int, returns=int,default_parameter1 = x)
... exp = lambda : add(a,x)
File "<stdin>", line 3
exp = lambda : add(a,x)
^
SyntaxError: invalid syntax
>>> ladd.append(exp)
File "<stdin>", line 1
ladd.append(exp)
^
IndentationError: unexpected indent
>>>
Decorator syntax is merely syntactic sugar, albeit one that directs people's thoughts into interesting directions.
#expr
def f(...):
...
is identical to
def f(...):
...
f = expr(f)
So you can just use attrs(argument_types=..., ...)(lambda: ...).
The # syntax is just syntactic sugar for calling the decorator with the next function as it's argument. This means that
#deco
def func(): pass
is the same as
def func(): pass
func = deco(func)
So what you want is simply:
ladd=[]
for x in range(0,10):
deco = attrs(argument_types=int, returns=int,default_parameter1 = x)
addx = functools.partial(add, 2)
# append the "decorated" function
ladd.append(deco(addx))

recursive lambda-expressions possible?

I'm trying to write a lambda-expression that calls itself, but i can't seem to find any syntax for that, or even if it's possible.
Essentially what I wanted to transfer the following function into the following lambda expression: (I realize it's a silly application, it just adds, but I'm exploring what I can do with lambda-expressions in python)
def add(a, b):
if a <= 0:
return b
else:
return 1 + add(a - 1, b)
add = lambda a, b: [1 + add(a-1, b), b][a <= 0]
but calling the lambda form of add results in a runtime error because the maximum recursion depth is reached. Is it even possible to do this in python? Or am I just making some stupid mistake? Oh, I'm using python3.0, but I don't think that should matter?
Maybe you need a Y combinator?
Edit - make that a Z combinator (I hadn't realized that Y combinators are more for call-by-name)
Using the definition of the Z combinator from Wikipedia
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
Using this, you can then define add as a completely anonymous function (ie. no reference to its name in its definition)
>>> add = Z(lambda f: lambda a, b: b if a <= 0 else 1 + f(a - 1, b))
>>> add(1, 1)
2
>>> add(1, 5)
6
Perhaps you should try the Z combinator, where this example is from:
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
>>> fact = lambda f: lambda x: 1 if x == 0 else x * f(x-1)
>>> Z(fact)(5)
120
First of all recursive lambda expressions are completely unnecessary. As you yourself point out, for the lambda expression to call itself, it needs to have a name. But lambda expressions is nothing else than anonymous functions. So if you give the lambda expression a name, it's no longer a lambda expression, but a function.
Hence, using a lambda expression is useless, and will only confuse people. So create it with a def instead.
But yes, as you yourself discovered, lambda expressions can be recursive. Your own example is. It's in fact so fantastically recursive that you exceed the maximum recursion depth. So it's recursive alright. Your problem is that you always call add in the expression, so the recursion never stops. Don't do that. Your expression can be expressed like this instead:
add = lambda a, b: a > 0 and (1 + add(a-1, b)) or b
Which takes care of that problem. However, your first def is the correct way of doing it.
add = lambda a, b: b if a <= 0 else 1 + add(a - 1, b)
You want the Y combinator, or some other fixed point combinator.
Here's an example implementation as a Python lambda expression:
Y = lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg)))
Use it like so:
factorial = Y(lambda f: (lambda num: num and num * f(num - 1) or 1))
That is, you pass into Y() a single-argument function (or lambda), which receives as its argument a recursive version of itself. So the function doesn't need to know its own name, since it gets a reference to itself instead.
Note that this does get tricky for your add() function because the Y combinator only supports passing a single argument. You can get more arguments by currying -- but I'll leave that as an exercise for the reader. :-)
a little late ... but I just found this gem # http://metapython.blogspot.com/2010/11/recursive-lambda-functions.html
def myself (*args, **kw):
caller_frame = currentframe(1)
code = caller_frame.f_code
return FunctionType(code, caller_frame.f_globals)(*args,**kw)
print "5! = "
print (lambda x:1 if n <= 1 else myself(n-1)*n)(5)

Categories