Wybór, próbka i wybory do losowego wybierania elementów z listy w Pythonie.

Biznes

Funkcje choice(), sample() i choices() w module random standardowej biblioteki Pythona mogą być użyte do losowego wybierania i pobierania elementów z listy, krotki, łańcucha lub innego obiektu sekwencji (losowe próbkowanie).

choice() pobiera pojedynczy element, sample() i choices() pobierają listę wielu elementów. sample() jest nieodzyskiwalną ekstrakcją bez duplikatów, choices() jest odzyskiwalną ekstrakcją z duplikatami.

Podane są tu następujące informacje.

  • Wybierz losowo jeden element.: random.choice()
  • Losowo wybierz wiele elementów (bez duplikatów): random.sample()
  • Losowo wybierz wiele elementów (z duplikatami): random.choices()
  • Ustalenie nasion liczb losowych

Wybierz losowo jeden element.: random.choice()

Za pomocą funkcji select() modułu random, jeden element jest losowo wybierany z listy i może zostać pobrany.

import random

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

print(random.choice(l))
# 1

To samo dotyczy tupli i łańcuchów. W przypadku łańcuchów wybierany jest pojedynczy znak.

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

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

Błąd, jeśli jako argument podano pustą listę, tuple lub łańcuch.

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

Losowo wybierz wiele elementów (bez duplikatów): random.sample()

Za pomocą funkcji sample() modułu random, możesz pobrać losowo wiele elementów z listy. Nie dochodzi do duplikacji elementów (nieodzyskiwalne pobieranie).

Pierwszym argumentem jest lista, a drugim liczba elementów do pobrania. Lista jest zwracana.

import random

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

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

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

Jeśli drugi argument jest ustawiony na 1, to zwracana jest również lista z jednym elementem; jeśli jest ustawiony na 0, to lista jest pusta. Jeśli drugi argument jest równy 1, zwracana jest lista z jednym elementem; jeśli jest równy 0, zwracana jest pusta lista; jeśli pierwszy argument jest większy niż liczba elementów na liście, pojawia się błąd.

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

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

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

Jeśli pierwszym argumentem jest tuple lub string, to zwracana jest nadal lista.

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

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

Jeśli chcesz powrócić do tuple'a lub łańcucha, użyj tuple(),join().

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

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

Zauważ, że wartość nie jest oceniana, więc jeśli oryginalna lista lub tuple zawiera elementy o tej samej wartości, istnieje możliwość, że ta sama wartość zostanie wybrana.

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

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

Jeśli chcesz uniknąć zduplikowanych wartości, możesz użyć set(), aby przekonwertować go na zestaw (typ set) i wyodrębnić tylko unikalne elementy, a następnie użyć sample().

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

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

Losowo wybierz wiele elementów (z duplikatami): random.choices()

Funkcja choices() modułu random pozwala na losowe pobranie wielu elementów z listy i w przeciwieństwie do funkcji sample(), pozwala na wybranie zduplikowanych elementów.

choices() jest funkcją dodaną w Pythonie 3.6. Nie jest ona dostępna we wcześniejszych wersjach.

Argument k określa liczbę elementów, które mają zostać pobrane. Duplikacja jest dozwolona, więc liczba elementów do pobrania może być większa niż liczba elementów na oryginalnej liście.

Ponieważ k jest argumentem typu keyword-only, konieczne jest podanie słowa kluczowego, takiego jak 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]

Domyślną wartością k jest 1; jeśli zostanie pominięte, zwracana jest lista z 1 elementem.

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

Argument weights może być użyty do określenia wagi (prawdopodobieństwa), że każdy element zostanie wybrany, a typem elementów na liście może być int lub float.

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]

Argument cum_weights może być również określony jako waga skumulowana. Waga cum_weights w poniższym przykładowym kodzie jest równoważna pierwszej z powyższych wag.

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

Domyślną wartością dla obu argumentów weights i cum_weights jest None, co oznacza, że każdy element jest wybierany z takim samym prawdopodobieństwem.

Jeśli długość (liczba elementów) argumentu weights lub cum_weights jest różna od oryginalnej listy, pojawia się błąd.

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

Błędem jest również równoczesne określenie wag i cum_weights.

# 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

Do tej pory w przykładowym kodzie jako pierwszy argument podawaliśmy listę, ale to samo dotyczy tupli i łańcuchów.

Ustalenie nasion liczb losowych

Przez podanie dowolnej liczby całkowitej do funkcji seed() modułu random, ziarno liczb losowych może zostać ustalone i generator liczb losowych może zostać zainicjalizowany.

Po inicjalizacji z tym samym ziarnem, elementy są zawsze wybierane w ten sam sposób.

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

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