Python is so flexible, that I can use functions as elements of lists or arguments of other functions. For example:
x = [sin, cos]
y = s[0](3.14) # It returns sin(3.14)
or
def func(f1, f2):
return f1(2.0) + f2(3.0)
However, it is not clear to me how to do the same with random functions. For example I want to use Gaussian distributions: [random.normalvariate(3.0, 2.0), random.normalvariate(1.0, 4.0)]
. In this example I will get a fixed list containing two elements. But what I want to get, is a list with random elements. What is a good way to do it in python?
Functions are data, and therefore can be passed around just like other values. This means a function can be passed to another function as an argument. This allows the function being called to use the function argument to carry out its action.
Because functions are objects we can pass them as arguments to other functions. Functions that can accept other functions as arguments are also called higher-order functions.
random. choice() accepts one argument: the list from which you want to select an item. You may encounter a scenario where you want to choose an item randomly from a list.
Methods are passed as arguments just like a variable. In this example, we define a class and its objects. We create an object to call the class methods. Now, to call a passed method or function, you just use the name it's bound to in the same way you would use the method's (or function's) regular name.
Try it with lambda
functions:
[lambda: random.normalvariate(3.0, 2.0), lambda: random.normalvariate(1.0, 4.0)]
You see the difference with parentheses. sin
is a function, sin(x)
is the return value of this function. As you cannot create a function without parentheses representing random.normalvariate(1.0, 4.0)
, you have to define it as a lambda function.
Use functools.partial or lambda
Those are basically the same:
[lambda: normalvariate(3, 2), ...]
# or
[partial(normalvariate, 3, 2), ...]
They are both equivalent to:
def _function():
return normalvariate(3, 2)
[_function, ...]
partial
is more flexible, gives you much better control over creation of _function
and lets you avoid lambda syntax clutter.
By the way, there were some controversions over lambda in the Python community, but in the end Guido admitted that finding a superior alternative to the lambda expression is "an impossible quest."
You should use partial from functools:
import functools
arg_sets = [(3.0, 2.0), (1.0, 4.0)]
myfuncs = [functools.partial(random.normalvariate, *args) for args in arg_sets]
myfuncs[0]()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With