Keuze, steekproef, en keuzes om willekeurig elementen uit een lijst te selecteren in Python.

Bedrijf

De functies choice(), sample(), en choices() in de random module van de Python standaardbibliotheek kunnen worden gebruikt om willekeurig elementen te selecteren en op te halen uit een lijst, tuple, string, of ander sequentie-object (random sampling).

choice() krijgt een enkel element, sample() en choices() krijgen een lijst van meerdere elementen. sample() is een niet-herstelbare extractie zonder doublures, choices() is een herstelbare extractie met doublures.

De volgende informatie wordt hier verstrekt.

  • Kies een willekeurig element.: random.choice()
  • Willekeurig meerdere elementen selecteren (geen doublures): random.sample()
  • Willekeurig meerdere elementen selecteren (met doublures): random.choices()
  • Zet het zaad van de willekeurige getallen vast

Kies een willekeurig element.: random.choice()

Met de functie choose() van de random module wordt één element willekeurig uit de lijst gekozen en kan het worden opgehaald.

import random

l = [0, 1, 2, 3, 4]

print(random.choice(l))
# 1

Hetzelfde geldt voor tupels en tekenreeksen. In het geval van tekenreeksen wordt één enkel teken geselecteerd.

print(random.choice(('xxx', 'yyy', 'zzz')))
# yyy

print(random.choice('abcde'))
# b

Fout als een lege lijst, tupel of string als argument wordt opgegeven.

# print(random.choice([]))
# IndexError: Cannot choose from an empty sequence

Willekeurig meerdere elementen selecteren (geen doublures): random.sample()

Met de functie sample() van de random module kun je meerdere elementen willekeurig uit een lijst halen. Er is geen duplicatie van elementen (niet-herstelbare extractie).

Het eerste argument is een lijst, en het tweede argument is het aantal elementen dat moet worden opgehaald. De lijst wordt teruggezonden.

import random

l = [0, 1, 2, 3, 4]

print(random.sample(l, 3))
# [2, 4, 0]

print(type(random.sample(l, 3)))
# <class 'list'>

Indien het tweede argument gelijk is aan 1, wordt eveneens een lijst met één element teruggegeven; indien het tweede argument gelijk is aan 0, is de lijst leeg. Indien het tweede argument 1 is, wordt een lijst met één element teruggegeven; indien het 0 is, wordt een lege lijst teruggegeven; indien het eerste argument meer is dan het aantal elementen in de lijst, treedt een fout op.

print(random.sample(l, 1))
# [3]

print(random.sample(l, 0))
# []

# print(random.sample(l, 10))
# ValueError: Sample larger than population or is negative

Indien het eerste argument een tuple of een string is, is wat teruggegeven wordt nog steeds een lijst.

print(random.sample(('xxx', 'yyy', 'zzz'), 2))
# ['xxx', 'yyy']

print(random.sample('abcde', 2))
# ['b', 'e']

Als je wilt terugkeren naar een tuple of string, gebruik dan tuple(),join().

print(tuple(random.sample(('xxx', 'yyy', 'zzz'), 2)))
# ('xxx', 'yyy')

print(''.join(random.sample('abcde', 2)))
# dc

Merk op dat de waarde niet wordt beoordeeld, dus als de oorspronkelijke lijst of tupel elementen met dezelfde waarde bevat, bestaat de mogelijkheid dat dezelfde waarde wordt geselecteerd.

l_dup = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]

print(random.sample(l_dup, 3))
# [3, 1, 1]

Als je dubbele waarden wilt vermijden, kun je set() gebruiken om het te converteren naar een set (set type) en alleen de unieke elementen te extraheren, en dan sample() gebruiken.

print(set(l_dup))
# {0, 1, 2, 3}

print(random.sample(set(l_dup), 3))
# [1, 3, 2]

Willekeurig meerdere elementen selecteren (met doublures): random.choices()

Met de functie keuzes() van de random module kan je meerdere elementen willekeurig uit een lijst halen, en in tegenstelling tot sample(), kunnen dubbele elementen worden geselecteerd.

keuzes() is een functie die in Python 3.6 is toegevoegd. Het is niet beschikbaar in eerdere versies.

Het argument k specificeert het aantal elementen dat moet worden opgehaald. Duplicatie is toegestaan, dus het aantal op te halen elementen kan groter zijn dan het aantal elementen in de oorspronkelijke lijst.

Aangezien k een sleutelwoord-argument is, is het nodig een sleutelwoord te specificeren, zoals k=3.

import random

l = [0, 1, 2, 3, 4]

print(random.choices(l, k=3))
# [2, 1, 0]

print(random.choices(l, k=10))
# [3, 4, 1, 4, 4, 2, 0, 4, 2, 0]

De standaardwaarde van k is 1; indien deze wordt weggelaten, wordt een lijst met 1 element teruggegeven.

print(random.choices(l))
# [1]

Het argument gewichten kan worden gebruikt om het gewicht (de waarschijnlijkheid) te specificeren dat elk element zal worden geselecteerd, en het type van de elementen in de lijst kan int of float zijn.

print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1]))
# [0, 2, 3]

print(random.choices(l, k=3, weights=[1, 1, 0, 0, 0]))
# [0, 1, 1]

Het argument cum_gewichten kan ook worden opgegeven als een cumulatief gewicht. De cum_gewichten in de volgende voorbeeldcode zijn gelijkwaardig aan de eerste gewichten hierboven.

print(random.choices(l, k=3, cum_weights=[1, 2, 3, 13, 14]))
# [3, 2, 3]

De standaardwaarde voor zowel de argumenten gewichten als cum_gewichten is Geen, wat betekent dat elk element met dezelfde waarschijnlijkheid wordt geselecteerd.

Indien de lengte (aantal elementen) van het argument weights of cum_weights verschillend is van de oorspronkelijke lijst, treedt een fout op.

# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1, 1, 1]))
# ValueError: The number of weights does not match the population_

Het is ook een fout om tegelijkertijd gewichten en cum_gewichten op te geven.

# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1], cum_weights=[1, 2, 3, 13, 14]))
# TypeError: Cannot specify both weights and cumulative weights

We hebben als voorbeeld in de voorbeeldcode tot nu toe een lijst als eerste argument opgegeven, maar hetzelfde geldt voor tupels en strings.

Zet het zaad van de willekeurige getallen vast

Door een willekeurig geheel getal aan de functie seed() van de random module te geven, kan het random getalzaad worden vastgesteld en kan de random getalgenerator worden geïnitialiseerd.

Na initialisatie met hetzelfde zaad worden de elementen altijd op dezelfde manier geselecteerd.

random.seed(0)
print(random.choice(l))
# 3

random.seed(0)
print(random.choice(l))
# 3