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 -- http://mail.python.org/mailman/listinfo/python-list