Roman
Roman

Reputation: 131038

How to pass a random function as an argument?

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

Answers (3)

Jakub M.
Jakub M.

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

Simon Bergot
Simon Bergot

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

eumiro
eumiro

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

Related Questions