Velocity Reviews > Dispatching functions from a dictionary

Dispatching functions from a dictionary

tkpmep@gmail.com
Guest
Posts: n/a

 03-30-2008
To keep a simulation tidy, I created a dispatcher that generates
random variables drawn from various distributions as follows:

import random

RVType = 1 #Type of random variable - pulled from RVDict

RVDict= {'1': random.betavariate(1,1), '2': random.expovariate(1),
'3': random.gammavariate(1,1), '4': random.gauss(0,1),
'5': random.lognormvariate(1,1), '6':
random.paretovariate(1),
'7': random.uniform( -1,1), '8':
random.weibullvariate(1,2) }

x = []
y=[]

rv = RVDict[str(RVType)]
for i in range(N):
x.append(rv)
y.append(rv)

Oddly, x and y get filled with a single value repeated N times. I
expected to get a different random number appear each time I called
rv ,but this does not happen. Instead, my first call to rv generates a
random number from the appropriate distribution, while subsequent
calls simply repeat the random number generated in the first call.
Where am I going wrong?

Sincerely

Thomas Philips

Paul Rubin
Guest
Posts: n/a

 03-30-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:
> RVDict= {'1': random.betavariate(1,1), '2': random.expovariate(1), ...}

This actually calls the functions random.betavariate, etc. when
initializing RVDict. If you print out the contents of RVDict you'll see
that each value in it is just a floating point number, not a callable.

You want something like:

RVDict = {'1': lambda: random.betavariate(1,1),
'2': lambda: random.expovariate(1), etc.

The "lambda" keyword creates a function that when called evaluates the
expression that you gave it. For example, lambda x: x*x is a function
that squares its argument, so saying

y = (lambda x: x*x) (3)

is similar to saying:

def square(x): return x*x
y = square(3)

Both of them set y to 9. In the case of lambda: random.expovariate(1)
you have made a function with no args, so you'd call it like this:

> rvfunc = RVDict[str(RVType)]
> for i in range(N):
> x.append(rvfunc())
> y.append(rvfunc())

rvfunc (the retrieved dictionary item) is now a callable function
instead of just a number. It takes no args, so you call it by saying
rvfunc().

George Sakkis
Guest
Posts: n/a

 03-30-2008
On Mar 30, 5:06 pm, Paul Rubin <http://(E-Mail Removed)> wrote:
> (E-Mail Removed) writes:
> > RVDict= {'1': random.betavariate(1,1), '2': random.expovariate(1), ...}

>
> This actually calls the functions random.betavariate, etc. when
> initializing RVDict. If you print out the contents of RVDict you'll see
> that each value in it is just a floating point number, not a callable.
>
> You want something like:
>
> RVDict = {'1': lambda: random.betavariate(1,1),
> '2': lambda: random.expovariate(1), etc.

In Python 2.5, you can also write this as:

from functools import partial

RVDict = {'1': partial(random.betavariate,1,1),
'2': partial(random.expovariate,1),
etc.

George

tkpmep@gmail.com
Guest
Posts: n/a

 03-31-2008
Paul, George,

Thanks a mill - the help is greatly appreciated.

Thomas Philips

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Mark Java 4 01-12-2011 04:21 PM jobs239@hotmail.com Java 4 07-20-2005 09:19 AM umer Java 0 05-04-2005 07:00 PM Xiangliang Meng C++ 1 06-21-2004 03:11 AM Terry C++ 1 08-31-2003 08:32 AM