bpo-40541: Add optional *counts* parameter to random.sample() (GH-19970)

This commit is contained in:
Raymond Hettinger 2020-05-08 07:53:15 -07:00 committed by GitHub
parent 2effef7453
commit 81a5fc38e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 13 deletions

View file

@ -217,7 +217,7 @@ Functions for sequences
The optional parameter *random*.
.. function:: sample(population, k)
.. function:: sample(population, k, *, counts=None)
Return a *k* length list of unique elements chosen from the population sequence
or set. Used for random sampling without replacement.
@ -231,6 +231,11 @@ Functions for sequences
Members of the population need not be :term:`hashable` or unique. If the population
contains repeats, then each occurrence is a possible selection in the sample.
Repeated elements can be specified one at a time or with the optional
keyword-only *counts* parameter. For example, ``sample(['red', 'blue'],
counts=[4, 2], k=5)`` is equivalent to ``sample(['red', 'red', 'red', 'red',
'blue', 'blue'], k=5)``.
To choose a sample from a range of integers, use a :func:`range` object as an
argument. This is especially fast and space efficient for sampling from a large
population: ``sample(range(10000000), k=60)``.
@ -238,6 +243,9 @@ Functions for sequences
If the sample size is larger than the population size, a :exc:`ValueError`
is raised.
.. versionchanged:: 3.9
Added the *counts* parameter.
.. deprecated:: 3.9
In the future, the *population* must be a sequence. Instances of
:class:`set` are no longer supported. The set must first be converted
@ -420,12 +428,11 @@ Simulations::
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']
>>> # Deal 20 cards without replacement from a deck of 52 playing cards
>>> # and determine the proportion of cards with a ten-value
>>> # (a ten, jack, queen, or king).
>>> deck = collections.Counter(tens=16, low_cards=36)
>>> seen = sample(list(deck.elements()), k=20)
>>> seen.count('tens') / 20
>>> # Deal 20 cards without replacement from a deck
>>> # of 52 playing cards, and determine the proportion of cards
>>> # with a ten-value: ten, jack, queen, or king.
>>> dealt = sample(['tens', 'low cards'], counts=[16, 36], k=20)
>>> dealt.count('tens') / 20
0.15
>>> # Estimate the probability of getting 5 or more heads from 7 spins