Funkcie choice(), sample() a choices() v module random štandardnej knižnice Python možno použiť na náhodný výber a získanie prvkov zo zoznamu, tuplu, reťazca alebo iného objektu sekvencie (náhodné vzorkovanie).
funkcia choice() získava jeden prvok, funkcie sample() a choices() získavajú zoznam viacerých prvkov. funkcia sample() je neobnoviteľná extrakcia bez duplikátov, funkcia choices() je obnoviteľná extrakcia s duplikátmi.
Tu sú uvedené tieto informácie.
- Náhodne vyberte jeden prvok.:
random.choice()
- Náhodný výber viacerých prvkov (bez duplikátov):
random.sample()
- Náhodný výber viacerých prvkov (s duplikátmi):
random.choices()
- Oprava osiva náhodného čísla
Náhodne vyberte jeden prvok.: random.choice()
Pomocou funkcie choose() modulu random sa zo zoznamu náhodne vyberie jeden prvok, ktorý je možné načítať.
import random
l = [0, 1, 2, 3, 4]
print(random.choice(l))
# 1
To isté platí pre tuply a reťazce. V prípade reťazcov sa vyberá jeden znak.
print(random.choice(('xxx', 'yyy', 'zzz')))
# yyy
print(random.choice('abcde'))
# b
Chyba, ak je ako argument zadaný prázdny zoznam, tuple alebo reťazec.
# print(random.choice([]))
# IndexError: Cannot choose from an empty sequence
Náhodný výber viacerých prvkov (bez duplikátov): random.sample()
Pomocou funkcie sample() modulu random môžete náhodne získať viacero prvkov zo zoznamu. Nedochádza k duplikácii prvkov (neobnoviteľná extrakcia).
Prvý argument je zoznam a druhý argument je počet prvkov, ktoré sa majú získať. Vráti sa zoznam.
import random
l = [0, 1, 2, 3, 4]
print(random.sample(l, 3))
# [2, 4, 0]
print(type(random.sample(l, 3)))
# <class 'list'>
Ak je druhý argument nastavený na 1, vráti sa zoznam s jedným prvkom; ak je nastavený na 0, zoznam je prázdny. Ak je druhý argument 1, vráti sa zoznam s jedným prvkom; ak je 0, vráti sa prázdny zoznam; ak je prvý argument väčší ako počet prvkov v zozname, nastane chyba.
print(random.sample(l, 1))
# [3]
print(random.sample(l, 0))
# []
# print(random.sample(l, 10))
# ValueError: Sample larger than population or is negative
Ak je prvým argumentom tuple alebo reťazec, vrátený zoznam je stále zoznam.
print(random.sample(('xxx', 'yyy', 'zzz'), 2))
# ['xxx', 'yyy']
print(random.sample('abcde', 2))
# ['b', 'e']
Ak chcete vrátiť tuple alebo reťazec, použite tuple(),join().
print(tuple(random.sample(('xxx', 'yyy', 'zzz'), 2)))
# ('xxx', 'yyy')
print(''.join(random.sample('abcde', 2)))
# dc
Všimnite si, že hodnota sa neposudzuje, takže ak pôvodný zoznam alebo tuple obsahuje prvky s rovnakou hodnotou, existuje možnosť, že bude vybraná rovnaká hodnota.
l_dup = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]
print(random.sample(l_dup, 3))
# [3, 1, 1]
Ak sa chcete vyhnúť duplicitným hodnotám, môžete použiť funkciu set() na prevod na množinu (typ množiny) a vybrať len jedinečné prvky a potom použiť funkciu sample().
print(set(l_dup))
# {0, 1, 2, 3}
print(random.sample(set(l_dup), 3))
# [1, 3, 2]
Náhodný výber viacerých prvkov (s duplikátmi): random.choices()
Funkcia choices() modulu random umožňuje náhodne získať viacero prvkov zo zoznamu a na rozdiel od funkcie sample() umožňuje vybrať duplicitné prvky.
Funkcia choices() bola pridaná v jazyku Python 3.6. V predchádzajúcich verziách nie je k dispozícii.
Argument k určuje počet prvkov, ktoré sa majú načítať. Duplikácia je povolená, takže počet prvkov, ktoré sa majú načítať, môže byť väčší ako počet prvkov v pôvodnom zozname.
Keďže k je argument len s kľúčovým slovom, je potrebné zadať kľúčové slovo, napríklad 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]
Predvolená hodnota k je 1; ak sa vynechá, vráti sa zoznam s 1 prvkom.
print(random.choices(l))
# [1]
Argument váhy možno použiť na určenie váhy (pravdepodobnosti), že každý prvok bude vybraný, a typ prvkov v zozname môže byť int alebo 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žno zadať aj ako kumulatívnu váhu. Parameter cum_weights v nasledujúcej ukážke kódu je ekvivalentný s prvými váhami uvedenými vyššie.
print(random.choices(l, k=3, cum_weights=[1, 2, 3, 13, 14]))
# [3, 2, 3]
Predvolené nastavenie pre argumenty weights a cum_weights je None, čo znamená, že každý prvok je vybraný s rovnakou pravdepodobnosťou.
Ak sa dĺžka (počet prvkov) argumentu weights alebo cum_weights líši od pôvodného zoznamu, nastane chyba.
# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1, 1, 1]))
# ValueError: The number of weights does not match the population_
Chybou je aj súčasné zadanie váh a 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
V doterajšej ukážke kódu sme ako prvý argument uviedli zoznam, ale to isté platí aj pre tuply a reťazce.
Oprava osiva náhodného čísla
Zadaním ľubovoľného celého čísla funkcii seed() modulu random je možné stanoviť semeno náhodného čísla a inicializovať generátor náhodných čísel.
Po inicializácii s rovnakým semienkom sa prvky vyberajú vždy rovnakým spôsobom.
random.seed(0)
print(random.choice(l))
# 3
random.seed(0)
print(random.choice(l))
# 3