Recipe 18.3. Generating Random Samples with ReplacementCredit: Sean Ross ProblemYou need to generate random samples with replacement out of a "population" of items that are held in a sequence. SolutionA generator for the purpose is quintessentially simple: import random def sample_wr(population, _choose=random.choice): while True: yield _choose(population) Discussionrandom.sample lets you do random sampling without replacement, and Recipe 18.4, which follows, shows a generator to perform sampling without replacement with excellent memory-consumption characteristics. This recipe provides a generator for sampling with replacement, which is an even simpler task. Basically all the work gets delegated to random.choice. The sample_wr generator shown in this recipe is unbounded: used on its own, it will keep looping forever. To bound the output of an intrinsically unbounded generator, you can use it in a for statement that at some point executes a break, or use other techniques shown in Recipe 19.2. For example, to make a random string of 50 lowercase ASCII letters: import itertools from string import ascii_lowercase x = ''.join(itertools.slice(sample_wr(ascii_lowercase), 50)) string.ascii_lowercase is exactly the string 'abcdefghijklmnopqrstuvwxyz'. If you didn't have the sample_wr generator, the equivalent code might be something like: from string import ascii_lowercase from random import choice x = ''.join([ random.choice(ascii_lowercase) for i in xrange(50) ]) So, the practical added-value of sample_wr is modest, when compared to other available building-blocks. It is, however, preferable to have such a fundamental concept of statistics as sampling with replacement embodied as its own function, rather than having to implement it with an explicit loop over random.choice each time it is needed. See AlsoLibrary Reference and Python in a Nutshell docs for module random. |