Welcome, guest | Sign In | My Account | Store | Cart

A simple function to permit you to generate random numbers by emulating a dice roll. The number of dice and the number of sides to each die are the parameters of the function. In order to (for example) roll 4d6, you would call dice( 4, 6 ).

Python, 2 lines
def dice( num, sides ):
	return reduce(lambda x, y, s = sides: x + random.randrange(s), range( num + 1 )) + num

Simulating a dice roll is a good way to generate a random number with an expected profile. For example, 3d6 will generate a bell-shaped probability curve with an average of 10.5.

After trying a more manual approach (for loop with an accumulator), I found that using reduce is generally faster. It's possible this implementation could be faster still, as I haven't profiled it very aggressively; it's fast enough for my purposes :)


Tim Keating (author) 18 years, 10 months ago  # | flag

Getting rid of reduce. Since reduce() is probably going away sometime soon, using a list comprehension or generator expression is a better way to do this in future Python:

from random import randrange

def dice(num, sides):
    return sum(randrange(sides)+1 for die in range(num))

Which is also more straightforward, come to think of it.

Frank P Mora 18 years, 7 months ago  # | flag

A list comprehension version. The inner most (furthest left) comprehension is an accumulator. The furthest right, an initializer. The result is a triply nested list so the stuff at the end is there to get only the final single digit result.

>>> dice=lambda s,n: [[[j for j in (j+randrange(s)+1,)] for die in range(n)] for j in (0,)]   [0][-1][0]
Created by Tim Keating on Wed, 19 Sep 2001 (PSF)
Python recipes (4591)
Tim Keating's recipes (3)
Python Cookbook Edition 1 (103)

Required Modules

  • (none specified)

Other Information and Tasks