]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
SF bug #801342: Bug (documentation or real, your choice) in random.sample.
authorRaymond Hettinger <python@rcn.com>
Fri, 5 Sep 2003 21:40:30 +0000 (21:40 +0000)
committerRaymond Hettinger <python@rcn.com>
Fri, 5 Sep 2003 21:40:30 +0000 (21:40 +0000)
random.sample() uses one of two algorithms depending on the ratio of the
sample size to the population size.  One of the algorithms accepted any
iterable population argument so long as it defined __len__().  The other
had a stronger requirement that the population argument be indexable.

While it met the documentation specifications which insisted that the
population argument be a sequence, it made random.sample() less usable
with sets.  So, the second algorithm was modified to coerce non-indexable
iterables and dictionaries into a tuple before proceeding.

Lib/random.py
Lib/test/test_random.py
Misc/NEWS

index b1d13c0dfb599e3ff9b9d533c8271ed8d0608db0..11059337f5d9341f265fff4844ee6d4294168086 100644 (file)
@@ -258,6 +258,10 @@ class Random(_random.Random):
                 result[i] = pool[j]
                 pool[j] = pool[n-i-1]   # move non-selected item into vacancy
         else:
+            try:
+                n > 0 and (population[0], population[n//2], population[n-1])
+            except (TypeError, KeyError):   # handle sets and dictionaries
+                population = tuple(population)
             selected = {}
             for i in xrange(k):
                 j = _int(random() * n)
index c9103e8f87b77f424c6787ef467f0da0c095de5a..a58a1054504a6ea44409df20274d3abb62bd0126 100644 (file)
@@ -86,6 +86,17 @@ class TestBasicOps(unittest.TestCase):
             else:
                 self.fail()
 
+    def test_sample_inputs(self):
+        # SF bug #801342 -- population can be any iterable defining __len__()
+        from sets import Set
+        self.gen.sample(Set(range(20)), 2)
+        self.gen.sample(range(20), 2)
+        self.gen.sample(xrange(20), 2)
+        self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2)
+        self.gen.sample(str('abcdefghijklmnopqrst'), 2)
+        self.gen.sample(unicode('abcdefghijklmnopqrst'), 2)
+        self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
+
     def test_gauss(self):
         # Ensure that the seed() method initializes all the hidden state.  In
         # particular, through 2.2.1 it failed to reset a piece of state used
index 9a9e0f8ff3f0db69dec19cebac11e7d5d80dea47..36e3237c2c52dfb1a937993f682520ca33759d87 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -67,6 +67,9 @@ Library
   allow any iterable.  Also the Set.update() has been deprecated because
   it duplicates Set.union_update().
 
+- Bug #801342:  random.sample() now accepts a Set as a possible argument.
+  Previously, it insisted that the population argument be indexable.
+
 - Bug #778964:  random.seed() now uses fractional seconds so that
   rapid successive, seeding calls will produce different sequences.