Функциите choice(), sample() и choices() в модула random на стандартната библиотека на Python могат да се използват за произволно избиране и извличане на елементи от списък, кортеж, низ или друг обект с последователност (произволна извадка).
функцията choice() получава единичен елемент, а функциите sample() и choices() получават списък от множество елементи. функцията sample() е невъзстановимо извличане без дубликати, а функцията choices() е възстановимо извличане с дубликати.
Тук се предоставя следната информация.
- Изберете един елемент на случаен принцип.:
random.choice()
- Случайно изберете няколко елемента (без дубликати):
random.sample()
- Случайно избиране на няколко елемента (с дубликати):
random.choices()
- Определяне на семената на случайните числа
Изберете един елемент на случаен принцип.: random.choice()
С функцията choose() на модула random един елемент се избира на случаен принцип от списъка и може да бъде извлечен.
import random
l = [0, 1, 2, 3, 4]
print(random.choice(l))
# 1
Същото важи и за кортежи и низове. При низовете се избира един символ.
print(random.choice(('xxx', 'yyy', 'zzz')))
# yyy
print(random.choice('abcde'))
# b
Грешка, ако като аргумент е посочен празен списък, кортеж или низ.
# print(random.choice([]))
# IndexError: Cannot choose from an empty sequence
Случайно изберете няколко елемента (без дубликати): random.sample()
С функцията sample() на модула random можете да получите произволно няколко елемента от даден списък. Няма дублиране на елементи (невъзстановимо извличане).
Първият аргумент е списък, а вторият аргумент е броят на елементите, които трябва да се извлекат. Връща се списъкът.
import random
l = [0, 1, 2, 3, 4]
print(random.sample(l, 3))
# [2, 4, 0]
print(type(random.sample(l, 3)))
# <class 'list'>
Ако вторият аргумент е равен на 1, също се връща списък с един елемент; ако е равен на 0, списъкът е празен. Ако вторият аргумент е 1, се връща списък с един елемент; ако е 0, се връща празен списък; ако първият аргумент е по-голям от броя на елементите в списъка, се получава грешка.
print(random.sample(l, 1))
# [3]
print(random.sample(l, 0))
# []
# print(random.sample(l, 10))
# ValueError: Sample larger than population or is negative
Ако първият аргумент е кортеж или низ, върнатият списък остава списък.
print(random.sample(('xxx', 'yyy', 'zzz'), 2))
# ['xxx', 'yyy']
print(random.sample('abcde', 2))
# ['b', 'e']
Ако искате да се върнете към кортеж или низ, използвайте tuple(),join().
print(tuple(random.sample(('xxx', 'yyy', 'zzz'), 2)))
# ('xxx', 'yyy')
print(''.join(random.sample('abcde', 2)))
# dc
Имайте предвид, че стойността не се преценява, така че ако оригиналният списък или кортеж съдържа елементи със същата стойност, има вероятност да бъде избрана същата стойност.
l_dup = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]
print(random.sample(l_dup, 3))
# [3, 1, 1]
Ако искате да избегнете дублиращи се стойности, можете да използвате функцията set(), за да я превърнете в множество (тип set) и да извлечете само уникалните елементи, след което да използвате функцията sample().
print(set(l_dup))
# {0, 1, 2, 3}
print(random.sample(set(l_dup), 3))
# [1, 3, 2]
Случайно избиране на няколко елемента (с дубликати): random.choices()
Функцията choices() на модула random позволява извличането на няколко елемента на случаен принцип от списък и за разлика от sample() позволява избирането на дублиращи се елементи.
choices() е функция, добавена в Python 3.6. Тя не е налична в по-ранните версии.
Аргументът k указва броя на елементите, които трябва да бъдат извлечени. Позволено е дублиране, така че броят на елементите, които ще бъдат извлечени, може да бъде по-голям от броя на елементите в оригиналния списък.
Тъй като k е аргумент само с ключова дума, е необходимо да се посочи ключова дума, например 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]
Стойността по подразбиране на k е 1; ако е пропусната, се връща списък с 1 елемент.
print(random.choices(l))
# [1]
Аргументът weights може да се използва за задаване на теглото (вероятността), с което ще бъде избран всеки елемент, а типът на елементите в списъка може да бъде int или 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]
Аргументът cum_weights може да бъде посочен и като кумулативно тегло. Cum_weights в следния примерен код е еквивалентен на първите тегла по-горе.
print(random.choices(l, k=3, cum_weights=[1, 2, 3, 13, 14]))
# [3, 2, 3]
По подразбиране и за двата аргумента weights и cum_weights е None, което означава, че всеки елемент се избира с еднаква вероятност.
Ако дължината (броят на елементите) на аргумента weights или cum_weights е различна от тази на оригиналния списък, се получава грешка.
# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1, 1, 1]))
# ValueError: The number of weights does not match the population_
Грешка е и едновременното задаване на weights и 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
В примерния код досега посочихме списък като първи аргумент, но същото важи и за кортежи и низове.
Определяне на семената на случайните числа
Чрез задаване на произволно цяло число на функцията seed() на модула random може да се фиксира семето на случайните числа и да се инициализира генераторът на случайни числа.
След инициализация с едно и също семе елементите винаги се избират по един и същ начин.
random.seed(0)
print(random.choice(l))
# 3
random.seed(0)
print(random.choice(l))
# 3