Converting a method with 2 variables to one variable [duplicate] - python

This question already has answers here:
Pass a function as a variable with one input fixed
(4 answers)
Closed 5 years ago.
I have a function foo that takes 2 arguments a and b. I want to create a list of functions that are similar to foo, but value of a is fixed.
def foo(a,b):
return a*b
fooList = []
for i in range(n):
fooList.append(foo(i))
I want fooList[i] to return a function that is similar to foo(i, b).

You can use functools.partial:
from functools import partial
def foo(a, b):
return a * b
fooList = []
for i in range(n):
fooList.append(partial(foo, i))
Then you'd do fooList[i](5) to calculate i * 5.
You can also curry lambda functions, somewhat like this:
for i in range(n):
fooList.append((lambda x: lambda y: x * y)(i))
You can then call that the same way as above.

Related

creating new functions based on another function [duplicate]

This question already has answers here:
Can a variable number of arguments be passed to a function?
(6 answers)
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 9 months ago.
I have a couple of functions defined like this (all parameters in a single array):
import numpy as np
def poly(x, params):
val = 0.
for i in range(len(params)):
val += params[-1 - i]*(x**i)
return val
a = 1.
b = 1.
c = 1.
params = [a, b, c]
Now I need to create the same function but without array as an argument of a function. I don't want to rewrite all my code, I need some new function for redefinition. The redefined function of my example should look like this:
def new_poly(x, a, b, c):
#take all parameters and put them back in an array to make the rest of the code work
params = [a, b, c]
val = 0.
for i in range(len(params)):
val += params[-1 - i]*(x**i)
return val
I will be grateful for any tips!
You can use *args:
def use_star_args(*args):
params = [*args]
print(params)
use_star_args(1, 2, 3)

Want to know how lamda function work in python [duplicate]

This question already has answers here:
Lambda in a loop [duplicate]
(4 answers)
Closed 10 months ago.
I'm trying to understand the lambda function in python and got this.
When I store the instance of lambda function in a Dict. It gives the expected result inside of the loop. But outside of the loop, it always stored the last instance, I think.
Can someone explain why this happening? and how the lambda function actually works when we store their instance.
Code:
d = {}
for x in range(4):
d[x] = lambda n: str(n*x)
print(d[x](1))
print(d[1](2))
print(d[2](2))
print(d[3](2))
Output:
0
1
2
3
6
6
6
given some x these 2 functions are equivalent:
f1 = lambda n: str(n * x)
def f2(n):
return str(n * x)
all you are doing in addition to that is to put several functions (for several values of x) in a dictionary.

Creating function: (f, n) which return f(f(f( .... x... ))) n times [duplicate]

This question already has answers here:
How to repeat a function n times
(7 answers)
Closed 4 years ago.
I am having trouble creating a higher order function in python that applies a function f, n times to generate a new function h, as its return value.
def compile(f, n)
# h is a function, f applied n times
...
return h
new = compile(lambda x: 2*x, 3)
new(4) == 32 # new(4) == 2(2(2(4)))
Since Python's functions are first-class citizens, a function can itself define a new function and return it. Defining a function inside a function can be done with def in the same way it would be in you top scope.
As a sidenote, I recommend you do not use compile as a function name as it does not accurately reflect what you are trying to do, which is called function composition, as well as overwrite the builtin function compile.
def compose_with_self(f, n):
def composed(arg):
for _ in range(n):
arg = f(arg)
return arg
return composed
Example:
def add_one(x):
return x + 1
add_three = compose_with_self(add_one, 3)
print(add_three(1)) # 4
You can do this easily using recursion
if n is zero, simply return x
otherwise, n is at least 1, apply f(x) to the recursive result compile (f, n - 1)
We can encode this in Python easily
def compile (f, n):
return lambda x: \
x if n is 0 else compile (f, n - 1) (f (x))
double_thrice = compile (lambda x: 2 * x, 3)
print (double_thrice (4))
# 32

Function restriction by fixing an argument [duplicate]

This question already has answers here:
Python Argument Binders
(7 answers)
Closed 6 months ago.
How should I make function with lesser dimensionality than the original one by fixing an
argument of it:
For example I want to make successor function out of sum function as follows:
def add(x, y):
return x + y
Now I am looking for something like this:
g = f(~, 1) which would be the successor function, i.e. g(x) = x+1.
You can write your own function:
def g(y):
return f(2, y)
Or more concisely:
g = lambda y: f(2, y)
There's also functools.partial:
import functools
def f(x, y):
return x + y
g = functools.partial(f, 2)
You can then call it as before:
>>> g(3)
5
If you do more than a little of this then you could use something like a decorator.
def with_x(x, fn, name=None):
def foo(*args, **kwargs):
return fn(x, *args, **kwargs)
if name:
foo.__name__ = name
return foo
def example(x,y):
return x**y
g = with_x(2, example)
g(3) #8
Use name = parameter if you care about the __name__ of the resulting function. You could get fancier with other hacks into the enclosed function innards possibly using the __inspect__ module if need be. But then you have re-written the previously mentioned functools partial stuff just to avoid having to give keyword arguments.

About python closure [duplicate]

This question already has answers here:
Creating functions (or lambdas) in a loop (or comprehension)
(6 answers)
Closed 6 months ago.
Below is an example I got from someone's blog about python closure.
I run it in python 2.7 and get a output different from my expect.
flist = []
for i in xrange(3):
def func(x):
return x*i
flist.append(func)
for f in flist:
print f(2)
My expected output is: 0, 2, 4
But the output is: 4, 4, 4
Is there anyone could help to explain it?
Thank you in advance.
Loops do not introduce scope in Python, so all three functions close over the same i variable, and will refer to its final value after the loop finishes, which is 2.
It seems as though nearly everyone I talk to who uses closures in Python has been bitten by this. The corollary is that the outer function can change i but the inner function cannot (since that would make i a local instead of a closure based on Python's syntactic rules).
There are two ways to address this:
# avoid closures and use default args which copy on function definition
for i in xrange(3):
def func(x, i=i):
return x*i
flist.append(func)
# or introduce an extra scope to close the value you want to keep around:
for i in xrange(3):
def makefunc(i):
def func(x):
return x*i
return func
flist.append(makefunc(i))
# the second can be simplified to use a single makefunc():
def makefunc(i):
def func(x):
return x*i
return func
for i in xrange(3):
flist.append(makefunc(i))
# if your inner function is simple enough, lambda works as well for either option:
for i in xrange(3):
flist.append(lambda x, i=i: x*i)
def makefunc(i):
return lambda x: x*i
for i in xrange(3):
flist.append(makefunc(i))
You are not creating closures. You are generating a list of functions which each access the global variable i which is equal to 2 after the first loop. Thus you end up with 2 * 2 for each function call.
Each function accesses the global i.
functools.partial comes to rescue:
from functools import partial
flist = []
for i in xrange(3):
def func(x, multiplier=None):
return x * multiplier
flist.append(partial(func, multiplier=i))

Categories