]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #18844: Make the various ways for specifing weights produce the same results.
authorRaymond Hettinger <python@rcn.com>
Sat, 29 Oct 2016 23:55:36 +0000 (16:55 -0700)
committerRaymond Hettinger <python@rcn.com>
Sat, 29 Oct 2016 23:55:36 +0000 (16:55 -0700)
Lib/random.py
Lib/test/test_random.py
Misc/NEWS

index ef8cb05601831a13147fdfc78d239e8553d01d66..a047444502d9fd3e34fc927e4d684e50514aedbf 100644 (file)
@@ -344,10 +344,12 @@ class Random(_random.Random):
         the selections are made with equal probability.
 
         """
+        random = self.random
         if cum_weights is None:
             if weights is None:
-                choice = self.choice
-                return [choice(population) for i in range(k)]
+                _int = int
+                total = len(population)
+                return [population[_int(random() * total)] for i in range(k)]
             else:
                 cum_weights = list(_itertools.accumulate(weights))
         elif weights is not None:
@@ -355,7 +357,6 @@ class Random(_random.Random):
         if len(cum_weights) != len(population):
             raise ValueError('The number of weights does not match the population')
         bisect = _bisect.bisect
-        random = self.random
         total = cum_weights[-1]
         return [population[bisect(cum_weights, random() * total)] for i in range(k)]
 
index 4d5a8749c76c05a993239cd284a7767fa6bc94da..dd2715288a4f7eafad2b4258da7f2a5eab80be06 100644 (file)
@@ -629,6 +629,22 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
         self.assertTrue(stop < x <= start)
         self.assertEqual((x+stop)%step, 0)
 
+    def test_choices_algorithms(self):
+        # The various ways of specifing weights should produce the same results
+        choices = self.gen.choices
+        n = 13132817
+
+        self.gen.seed(8675309)
+        a = self.gen.choices(range(n), k=10000)
+
+        self.gen.seed(8675309)
+        b = self.gen.choices(range(n), [1]*n, k=10000)
+        self.assertEqual(a, b)
+
+        self.gen.seed(8675309)
+        c = self.gen.choices(range(n), cum_weights=range(1, n+1), k=10000)
+        self.assertEqual(a, c)
+
 def gamma(z, sqrt2pi=(2.0*pi)**0.5):
     # Reflection to right half of complex plane
     if z < 0.5:
index 75f0ba6afb78e4bf9b9511bda58be44516dc1326..d49162babdada96d7ac63c07b58c31d6a40c402c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -34,6 +34,9 @@ Library
 - Issue #27275: Fixed implementation of pop() and popitem() methods in
   subclasses of accelerated OrderedDict.
 
+- Issue #18844: The various ways of specifing weights for random.choices()
+  now produce the same result sequences.
+
 - Issue #28255: calendar.TextCalendar().prmonth() no longer prints a space
   at the start of new line after printing a month's calendar.  Patch by
   Xiang Zhang.