Le funzioni choice(), sample() e choices() nel modulo random della libreria standard di Python possono essere usate per selezionare e recuperare casualmente elementi da una lista, tupla, stringa o altro oggetto sequenza (campionamento casuale).
choice() ottiene un singolo elemento, sample() e choices() ottengono una lista di elementi multipli. sample() è un'estrazione non recuperabile senza duplicati, choices() è un'estrazione recuperabile con duplicati.
Le seguenti informazioni sono fornite qui.
- Seleziona un elemento a caso.:
random.choice()
- Seleziona casualmente più elementi (senza duplicati):
random.sample()
- Selezionare casualmente più elementi (con duplicati):
random.choices()
- Fissare il seme del numero casuale
Seleziona un elemento a caso.: random.choice()
Con la funzione choose() del modulo random, un elemento viene selezionato casualmente dalla lista e può essere recuperato.
import random
l = [0, 1, 2, 3, 4]
print(random.choice(l))
# 1
Lo stesso vale per le tuple e le stringhe. Nel caso delle stringhe, viene selezionato un singolo carattere.
print(random.choice(('xxx', 'yyy', 'zzz')))
# yyy
print(random.choice('abcde'))
# b
Errore se una lista, tupla o stringa vuota è specificata come argomento.
# print(random.choice([]))
# IndexError: Cannot choose from an empty sequence
Seleziona casualmente più elementi (senza duplicati): random.sample()
Con la funzione sample() del modulo random, potete ottenere più elementi a caso da una lista. Non c'è duplicazione di elementi (estrazione non recuperabile).
Il primo argomento è una lista e il secondo argomento è il numero di elementi da recuperare. La lista viene restituita.
import random
l = [0, 1, 2, 3, 4]
print(random.sample(l, 3))
# [2, 4, 0]
print(type(random.sample(l, 3)))
# <class 'list'>
Se il secondo argomento è impostato a 1, viene anche restituita una lista con un elemento; se è impostato a 0, la lista è vuota. Se il secondo argomento è 1, viene restituita una lista con un elemento; se è 0, viene restituita una lista vuota; se il primo argomento è più del numero di elementi della lista, si verifica un errore.
print(random.sample(l, 1))
# [3]
print(random.sample(l, 0))
# []
# print(random.sample(l, 10))
# ValueError: Sample larger than population or is negative
Se il primo argomento è una tupla o una stringa, ciò che viene restituito è ancora una lista.
print(random.sample(('xxx', 'yyy', 'zzz'), 2))
# ['xxx', 'yyy']
print(random.sample('abcde', 2))
# ['b', 'e']
Se volete tornare a una tupla o a una stringa, usate tuple(),join().
print(tuple(random.sample(('xxx', 'yyy', 'zzz'), 2)))
# ('xxx', 'yyy')
print(''.join(random.sample('abcde', 2)))
# dc
Notate che il valore non viene giudicato, quindi se la lista o la tupla originale contiene elementi con lo stesso valore, c'è la possibilità che lo stesso valore venga selezionato.
l_dup = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]
print(random.sample(l_dup, 3))
# [3, 1, 1]
Se volete evitare i valori duplicati, potete usare set() per convertirlo in un insieme (tipo set) ed estrarre solo gli elementi unici, e poi usare sample().
print(set(l_dup))
# {0, 1, 2, 3}
print(random.sample(set(l_dup), 3))
# [1, 3, 2]
Selezionare casualmente più elementi (con duplicati): random.choices()
La funzione choices() del modulo random permette di recuperare più elementi a caso da una lista e, a differenza di sample(), permette di selezionare elementi duplicati.
choices() è una funzione aggiunta in Python 3.6. Non è disponibile nelle versioni precedenti.
L'argomento k specifica il numero di elementi da recuperare. La duplicazione è permessa, quindi il numero di elementi da recuperare può essere maggiore del numero di elementi nella lista originale.
Poiché k è un argomento solo per parole chiave, è necessario specificare una parola chiave, come 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]
Il valore predefinito di k è 1; se viene omesso, viene restituita una lista con 1 elemento.
print(random.choices(l))
# [1]
L'argomento pesi può essere usato per specificare il peso (probabilità) che ogni elemento sarà selezionato, e il tipo degli elementi della lista può essere int o 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]
L'argomento cum_weights può anche essere specificato come peso cumulativo. Il cum_weights nel seguente codice di esempio è equivalente ai primi pesi di cui sopra.
print(random.choices(l, k=3, cum_weights=[1, 2, 3, 13, 14]))
# [3, 2, 3]
Il default per entrambi gli argomenti weights e cum_weights è None, il che significa che ogni elemento viene selezionato con la stessa probabilità.
Se la lunghezza (numero di elementi) dell'argomento weights o cum_weights è diversa dalla lista originale, si verifica un errore.
# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1, 1, 1]))
# ValueError: The number of weights does not match the population_
È anche un errore specificare pesi e cum_weights allo stesso tempo.
# 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
Abbiamo specificato una lista come primo argomento come esempio nel codice di esempio finora, ma lo stesso vale per tuple e stringhe.
Fissare il seme del numero casuale
Dando un numero intero arbitrario alla funzione seed() del modulo random, il seme del numero casuale può essere fissato e il generatore di numeri casuali può essere inizializzato.
Dopo l'inizializzazione con lo stesso seme, gli elementi sono sempre selezionati nello stesso modo.
random.seed(0)
print(random.choice(l))
# 3
random.seed(0)
print(random.choice(l))
# 3