I have the following straightforward function in Python 3:
def func(i,j):
return lambda i,j: (i*j)
Here's an example of what this function should do:
IN: func(4,'Hello')
OUT: ('Hello' 'Hello' 'Hello' 'Hello')
However, the actual output is an address in memory where the result is stored. What modification do I need to make?
If you want to return the value of i * j, then go ahead and return it. A lambda means it returns a function that acts as you want it to. Consider this:
def mul(x, y):
return x * y
def func(x, y):
return lambda x, y: x*y
Now let's take a look at a little shell session:
>>> mul(4, 'hello')
'hellohellohellohello'
>>> func(4, 'hello')
<function 'lambda' at ...>
>>> f = func(4, 'hello')
>>> f(4, 'hello')
'hellohellohellohello'
As you can see, when you use lambda, your function returns a function which, in turn, needs to be called. The arguments x and y have no correspondence to the arguments in the lambda function.
Since your expected output is a tuple of x lots of y, use a tuple in your function:
def func(i, j):
return (j,) * i
Related
How a function can be applied on top of another function like a(b)(x,y) where a and b are functions and x and y are arguments? Can somebody provide me with the term we call this concept along with some examples.
For a(b)(x, y) to make sense, a needs to be a function that takes b as an argument and produces a new function that takes two arguments. Here's an example:
>>> def a(func):
... def wrapped(x, y):
... return 2 * func(x, y)
... return wrapped
...
>>> def b(x, y):
... return x + y
...
>>> a(b)(1, 2)
6
In the above example a is a function that wraps a two-argument function and doubles its result. b(1, 2) is 3, and a(b)(1, 2) is therefore 6.
a function can be applied to another function like this
a(b)(x,y)
if the returned value from a(b) is a function that takes 2 arguments
in that case the function that is returned from a(b) will be applied on the parameters x,y
for example :
def mul(x,y):
return x*y
def add5_to_func(func):
return lambda x,y : func(x,y) + 5
print(add5_to_func(mul)(3,3)) # will print 14
CASE 1: ERROR output
def myfunc(n):
return lambda a : a * n
mytripler(11) = myfunc(3) => Error
===========================================
CASE 2: Correct output
def myfunc(n):
return lambda a : a * n
mytripler = myfunc(3)
print(mytripler(11))
How does the value 11 get passed to the method in the second case?
When myfunc is executed it is returning another function...
def myfunc(n):
Return lambda x : x*n
Is same as writing..
def myfunc(n):
def f(x):
Return x*n
return f
Hence in first function you are returning another function and as it has formed closure it has access to n variable of parent function.
It is because of the way lambda functions work, the value 11 is used in place of the variable 'a' in your case and n is already 3.
When mytripler = myfunc(3) is ran, it is returning a function(lambda) which looks like
def fun(a) :
return a * 3
Now the mytripler points to the above function "fun" which takes a single argument and multiplies it by 3.
Your function myfunc returns a function/callable (in this case lambda function), as can be seen here:
>>> def myfunc(n):
... return lambda a : a * n
>>> print(myfunc)
<function myfunc at 0x7efe15c9dea0>
Now, when we make the call to myfunc, the value passed as n will be bound in the lambda function:
>>> mytripler = myfunc(3)
>>> print(mytripler)
<function myfunc.<locals>.<lambda> at 0x7efe14f20598>
At this point mytripler is defined as lambda a : a * 3; the n was replaced by the value (or also: has been assgined the value) that we passed as argument to myfunc(). Note that this lambda construct is functionally equivalent to:
>>> def mytripler(a):
... return a * 3
Now, we can call mytripler with an value to make the final calculation/execution:
>>> mytripler(11)
33
Your error is that you cannot assign a value to a function call on the left-hand side:
>>> mytripler(11) = myfunc(3)
File "<input>", line 1
SyntaxError: can't assign to function call
But you can skip the intermediary step of assigning the result of myfunc to the name mytripler, and instead do both function calls chained together, like this:
>>> myfunc(3)(11)
33
Does that answer your question?
Code mock-up & expected results:
X = 10
Y = (X-10)/2
print(Y)
X = 12
print(Y)
I want this to print "0" and then "1", but obviously Y is not dynamically assigned.
I have tried utilizing lambda functions (a la Y = lambda i: (X-10)/2) to get this functionality, but I keep getting <function <lambda> at 0x7f5f6356eea0>.
This is just to avoid needing to run a function or redefine Y at the end of any function that alters the value of X.
Thanks in advance!
Alternatively, you can use properties as well:
class P:
def __init__(self, x):
self.__x = x
self.__y = x
#property
def x(self):
return self.__x
#property
def y(self):
return (self.__x - 10) / 2
#x.setter
def x(self, x):
self.__x = x
You will have to access the values through an instance of the P class, though.
p = P(10)
print(p.y)
p.x = 12
print(p.y)
I have tried utilizing lambda functions (a la Y = lambda i: (X-10)/2)
You need to call the function:
print(Y())
As for having print(Y) print the updated value? Mostly impossible, and what workarounds exist aren't anywhere near worth it. Just be explicit about recomputing the value.
You need to call the lambda:
print(Y())
Assigning a lamda to a variable is essentially the same as defining a function:
def Y():
return (X-10)/2
You can't do what you want with ordinary variables. Assigning a variable copies the value into it, it doesn't create a reference to the expression that was used.
You need to provide x argument to your lambda function. In your case this is 10 or 12.
y = lambda x: (x-10)/2
print(y(10))
>>> 0.0
Use a lambda with a dict to keep track of it:
>>> vars={}
>>> vars['x']=10
>>> vars['y']=lambda :(vars['x']-10.0)/2.0
>>> vars['y']()
0.0
>>> vars['x']=12.0
>>> vars['y']()
1.0
To assign the value using your lambda expression, you need to call it. You can do it in one line:
Y = (lambda i: (i-10)/2)(X)
There is no need for defining additional classes or functions, just add the parentheses and the argument.
The reason you are getting <function <lambda> at 0x7f5f6356eea0> is that a lambda expression produces a function, not the result of executing the function.
I am new to python. This might be a simple question, but if I have many functions that are dependent on each other how would I access lists from one function to use in another.
So...
def function_1():
list_1=[]
def function_2():
list_2= [2*x for x in list_1]
def function_3():
list_3= [x * y for x, y in zip(list_1, list_2)]
That is not the exact code but that is the idea of my problem. I would just put them all together in one function but I need them to be separate.
The correct way to do this would be to use a class. A class is an object that has internal variables (in your case, the three lists), and methods (functions that can access the internal methods). So, this would be:
class Foo(object):
def __init__(self, data=None):
self.list_1 = data if not data is None else []
def function_2():
self.list_2 = [2 * x for x in self.list_1]
And so on. For calling it:
foo = Foo() # list_1 is empty
foo2 = Foo([1,2,3]) # list_1 is not empty
foo2.function_2()
print foo2.list_2
# prints [2, 4, 6]
Make them arguments and return values:
def function_1():
return []
def function_2(list_1):
return [2*x for x in list_1]
def function_3(list_1, list_2):
return [x * y for x, y in zip(list_1, list_2)]
(this suggests that function_1 isn't much worth having...)
The exact way will depend on exactly how you want things to work, but here is a simple example:
def function_1():
return []
def function_2():
return [2*x for x in function_1()]
def function_3():
return [x * y for x, y in zip(function_1(), function_2())]
The key point is that functions do not generally just "do" things, they return things. If you have a value in one function that you want to use in another function, the first function should return that value. The second function should call the first function, and use its return value.
Functions are basically black boxes -- the outside world doesn't really know what goes on inside or what variables exist there. From the outside, other code only sees what goes in (the function's arguments) and what goes out (its return value).
So if your function computes some value that is to be used elsewhere, it should be returned as the result of the function.
E.g.,
def square(x):
return x * x
Takes a number, computes its square, and returns it.
Then you could do:
print(square(5))
and it will print 25.
So in your case you can return the lists and use them in the other functions, as the other answers showed:
def function_1():
return []
def function_2():
return [2*x for x in function_1()]
def function_3():
return [x * y for x, y in zip(function_1(), function_2())]
I work in Python. Recently, I discovered a wonderful little package called fn. I've been using it for function composition.
For example, instead of:
baz(bar(foo(x))))
with fn, you can write:
(F() >> foo >> bar >> baz)(x) .
When I saw this, I immediately thought of Clojure:
(-> x foo bar baz) .
But notice how, in Clojure, the input is on the left. I wonder if this possible in python/fn.
You can't replicate the exact syntax, but you can make something similar:
def f(*args):
result = args[0]
for func in args[1:]:
result = func(result)
return result
Seems to work:
>>> f('a test', reversed, sorted, ''.join)
' aestt'
You can't get that exact syntax, although you can get something like F(x)(foo, bar, baz). Here's a simple example:
class F(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, *funcs):
arg = self.arg
for f in funcs:
arg = f(arg)
return arg
def a(x):
return x+2
def b(x):
return x**2
def c(x):
return 3*x
>>> F(2)(a, b, c)
48
>>> F(2)(c, b, a)
38
This is a bit different from Blender's answer since it stores the argument, which can later be re-used with different functions.
This is sort of like the opposite of normal function application: instead of specifying the function up front and leaving some arguments to be specified later, you specify the argument and leave the function(s) to be specified later. It's an interesting toy but it's hard to think why you'd really want this.
If you want to use fn, with a little hack you can get a bit closer to Clojure syntax:
>>> def r(x): return lambda: x
>>> (F() >> r(x) >> foo >> bar >> baz)()
See how I added another function at the beginning of the composition chain that will just return x when called. The problem with this is that you still have to call your composed function, just without any arguments.
I think #Blender's answer is your best bet trying to emulate Clojure's thread function in Python.
I came up with this
def _composition(arg, *funcs_and_args):
"""
_composition(
[1,2,3],
(filter, lambda x: x % 2 == 1),
(map, lambda x: x+3)
)
#=> [4, 6]
"""
for func_and_args in funcs_and_args:
func, *b = func_and_args
arg = func(*b, arg)
return(arg)
This seems to work for simple input. Not sure it is worth the effort for complex input, e.g., ((42, 'spam'), {'spam': 42}).
def compose(function, *functions):
return function if not functions else \
lambda *args, **kwargs: function(compose(*functions)(*args, **kwargs))
def rcompose(*functions):
return compose(*reversed(functions))
def postfix(arg, *functions):
return rcompose(*functions)(arg)
Example:
>>> postfix(1, str, len, hex)
'0x1'
>>> postfix(1, hex, len)
3
My compose function that returns a function
def compose(*args):
length = len(args)
def _composeInner(lastResult, index):
if ((length - 1) < index):
return lastResult
return _composeInner(args[index](lastResult), index + 1)
return (lambda x: _composeInner(x, 0))
Usage:
fn = compose(
lambda x: x * 2,
lambda x: x + 2,
lambda x: x + 1,
lambda x: x / 3
)
result = fn(6) # -> 5
I understand what you mean. It doesn't make sense. In my opinion this python library
does it better.
>>> from compositions.compositions import Compose
>>> foo = Compose(lambda x:x)
>>> foo = Compose(lambda x:x**2)
>>> foo = Compose(lambda x:sin(x))
>>> (baz*bar*foo)(x)