randomly generate n of each of two types

Stargaming stargaming at gmail.com
Sun Feb 11 16:18:58 EST 2007


Alan Isaac schrieb:
> I need access to 2*n random choices for two types
> subject to a constraint that in the end I have
> drawn n of each.  I first tried::
> 
> def random_types(n,typelist=[True,False]):
>     types = typelist*n
>     random.shuffle(types)
>     for next_type in types:
>         yield next_type
> 
> This works but has some obvious costs.
> To avoid those I considered this instead::
> 
> def random_types(n,typelist=[True,False]):
>     type0, type1 = typelist
>     ct0, ct1 = 0,0
>     while ct0+ct1<2*n:
>         if random.random() < ((n-ct0)/(2*n-ct0-ct1)):
>             next_type = type0
>             ct0 += 1
>         else:
>             next_type = type1
>             ct1 += 1
>         yield next_type
> 
> Does this seem a good way to go?  Comments welcome.

I think there's any easier way using random's function `shuffle`.

 >>> from random import shuffle
 >>> def randomly(n, types):
...   types *= n
...   shuffle(types)
...   for x in types: yield x
...
 >>> randomly(1, [True, False])
<generator object at 0x00A62AA8>
 >>> list(randomly(1, [True, False]))
[True, False]
 >>> list(randomly(2, [True, False]))
[True, False, True, False]
 >>> list(randomly(4, [True, False]))
[False, True, False, False, False, True, True, True]

You can even do this with an arbitrary number of choices:
 >>> list(randomly(2, [True, False, None, NotImplemented]))
[NotImplemented, None, NotImplemented, False, False, None, True, True]

Notice that this method works in-place, ie
 >>> a = [True, False]
 >>> list(randomly(2, a))
[False, False, True, True]
 >>> a # a changed!
[False, False, True, True]

This can be changed by creating a copy, though.

HTH,
Stargaming



More information about the Python-list mailing list