Reputation: 131038
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?
Upvotes: 8
Views: 1019
Reputation: 33817
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."
Upvotes: 7
Reputation: 10582
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]()
Upvotes: 5
Reputation: 212835
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.
Upvotes: 8