diff --git a/Lib/random.py b/Lib/random.py --- a/Lib/random.py +++ b/Lib/random.py @@ -274,6 +274,21 @@ """Choose a random element from a non-empty sequence.""" return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty + def choice_try(self, seq): + """Choose a random element from a non-empty sequence.""" + try: + return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty + except IndexError: + return seq[-1] + + def choice_eq(self, seq): + """Choose a random element from a non-empty sequence.""" + n = len(seq) + i = int(self.random() * n) + if i == n: + i = n - 1 + return seq[i] # raises IndexError if seq is empty + def shuffle(self, x, random=None): """x, random=random.random -> shuffle list x in place; return None. ~/py27 $ py27 -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 100 loops, best of 3: 3.79 msec per loop ~/py27 $ py27 -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_try' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 100 loops, best of 3: 3.86 msec per loop ~/py27 $ py27 -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_eq' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 100 loops, best of 3: 4.09 msec per loop ~/py27 $ ~/py27 $ py27 -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 100 loops, best of 3: 3.75 msec per loop ~/py27 $ py27 -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_try' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 100 loops, best of 3: 3.95 msec per loop ~/py27 $ py27 -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_eq' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 100 loops, best of 3: 4.08 msec per loop ~/py27 $ ~/py27 $ cp Lib/random.py random.py ~/py27 $ pypy -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 10000 loops, best of 3: 140 usec per loop ~/py27 $ pypy -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_try' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 10000 loops, best of 3: 139 usec per loop ~/py27 $ pypy -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_eq' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 10000 loops, best of 3: 137 usec per loop ~/py27 $ ~/py27 $ pypy -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 10000 loops, best of 3: 141 usec per loop ~/py27 $ pypy -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_try' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 10000 loops, best of 3: 139 usec per loop ~/py27 $ pypy -m timeit -s 'import random' -s 'choice=random.Random(8675309).choice_eq' -s 'seq = [10, 20, 30]' 'for i in xrange(10000): choice(seq)' 10000 loops, best of 3: 136 usec per loop