back to top

Numeri random in Python

In questo post vedremo come generare numeri casuali attraverso il linguaggio di programmazione Python. Prima di passare al codice, tuttavia, è necessario chiarire cosa sia un numero casuale.

Un numero casuale (o numero random) è un valore numerico generato attraverso un processo non predeterminato, casuale, appunto. Questa definizione introduttiva potrebbe apparire scontata ma è necessaria per chiarire da subito un concetto apparentemente contraddittorio: in teoria i linguaggi di programmazione possono essere utilizzati per produrre dei numeri casuali ma nella realtà ci si deve riferire ad essi parlando di numeri pseudo casuali.

Differenza tra numeri casuali e numeri pseudo casuali

Un numero pseudo casuale presenta proprietà statistiche in buona parte simili a quelle dei numeri casuali tranne quella forse più rilevante, l’indeterminatezza.

Ciò accade perché un numero casuale generato da un linguaggio di programmazione, o più propriamente da un’applicazione basata su di esso, utilizza per questo scopo un algoritmo. Un algoritmo è rappresentato da delle istruzioni destinate a restituire un output in seguito alla manipolazione di un input, tali istruzioni vengono definite a priori e ciò esclude l’indeterminatezza. Naturalmente, più un algoritmo è complesso maggiore sarà l’approssimazione delle proprietà dei numeri pseudo casuali a quelle dei numeri casuali veri e propri, ma in qualche misura tali valori saranno sempre prevedibili.

Detto questo i numeri (pseudo) casuali possono essere utili in diversi ambiti della programmazione, basti pensare al video gaming, per la generazione degli scenari di gioco, o al machine learning, per la produzione di condizioni e comportamenti più o meno imprevedibili che rappresenteranno il contesto in cui verranno sviluppati i modelli di apprendimento.

Il modulo random di Python

Il riferimento al machine learning ci porta automaticamente a parlare di quello che sta diventando uno dei linguaggi di programmazione più utilizzati per le tecnologie basate su di esso: Python. In Python sono disponibili diversi strumenti per la RNG (Random Number Generation), in questo approfondimento verranno trattati quelli utilizzati più di frequente.

Il modulo random di Python è stato concepito appositamente per l’implementazione di generatori di numeri pseudo casuali. Nella sua applicazione più immediata esso fornisce un metodo chiamato random() che ha il compito di produrre un numero decimale (float) dal valore compreso tra 0 e 1. L’esecuzione di un’istruzione come la seguente:

# Generazione di numeri casuali in Python
import random
numero_casuale = random.random()
print(numero_casuale)

potrebbe generare in output la sequenza “0.6629126069331859”, così come “0.20027701305376144” o “0.20549576436251982” e così via. In ogni caso il costrutto prevede l’importazione del modulo tramite la keyword import, l’eventuale associazione della chiamata al metodo ad una variabile e la stampa a video del valore generato. Volendo ricorrere ad una sintassi essenziale sarebbe possibile ottenere il medesimo risultato tramite una stampa del risultato derivante dalla chiamata diretta al metodo:

import random
print(random.random())

Un altro caso interessante riguarda la generazione di numeri random compresi all’interno di un intervallo. Per far questo è possibile utilizzare un altro metodo denominato randint() che accetta come argomenti due valori denominati start e stop. Dato un valore X come start e un valore Y come stop, l’output N sarà un numero intero superiore ad X e inferiore a Y. Un’istruzione come quella proposta di seguito:

# Generazione di numeri casuali con randint()
import random
numero_intero_casuale = random.randint(2,43)
print(numero_intero_casuale)

potrebbe produrre “19”, così come “31” o “40”.

Per avere un maggior controllo sull’output Python prevede anche la possibilità di utilizzare il metodo seed() che ha il compito di inizializzare il generatore dei numeri random. Quest’ultimo necessita infatti di un valore (detto appunto “seed”) da cui partire per la generazione del numero casuale:

# Inizializzare il generatore di numeri casuali con un seed
import random
random.seed(9)
print(random.random())
# possibile output
# 0.46300735781502145

Per ottenere risultati differenti è necessario utilizzare valori diversi per il seed, la medesima istruzione eseguita 2 volte nella stessa espressione con il medesimo seed genererà infatti un output equivalente. Come è possibile notare grazie agli esempi proposti in precedenza, in Python il seed non deve essere necessariamente esplicitato e, quando assente, il generatore viene inizializzato tramite il valore corrispondente al system time corrente.

Liste e sequenze di numeri casuali

Python dispone di un tipo nativo, detto lista, con cui rappresentare delle sequenze mutabili, a lunghezza variabile, di oggetti. Nel caso dei numeri random le liste possono essere utilizzate per generare sequenze di valori prodotti casualmente, ciò è possibile attraverso l’uso di un costrutto d’iterazione come per esempio il ciclo for:

# Generare una lista di numeri random
import random
lista_numeri_casuali = []
for x in range(0,6):
  y = random.randint(1,45)
  lista_numeri_casuali.append(y)
  print(lista_numeri_casuali)

Nell’espressione viene creata innanzitutto una lista vuota (“lista_numeri_casuali[]”), successivamente viene inizializzato un ciclo for che prevede 6 interazioni alla fine delle quali verrà prodotta una sequenza composta da 6 valori interi, non necessariamente univoci, delimitati da un intervallo compreso tra 1 e 45. Ad ogni interazione successiva alla prima i valori prodotti vengono concatenati a quelli precedenti. L’output generato potrebbe essere quindi simile al seguente:

[31]
[31, 31]
[31, 31, 44]
[31, 31, 44, 16]
[31, 31, 44, 16, 1]
[31, 31, 44, 16, 1, 27]

Un’alternativa al costrutto precedente viene data dall’impiego del metodo sample(), appartenente anch’esso al modulo random, che ha il compito di generare immediatamente una lista:

import random
lista_numeri_casuali = random.sample(range(1, 45), 6)
print(lista_numeri_casuali)
# possibile output
# [42, 22, 15, 28, 33, 34]

In questo caso la chiamata al metodo viene effettuata passando ad esso come argomenti l’intervallo da cui estrarre casualmente i valori e il numero di valori che devono comporre la sequenza.

Numeri random con NumPy

Python offre le liste in sostituzione degli array disponibili con altri linguaggi di programmazione. Le liste possono essere manipolate come degli array ma funzionano in modo differente: mentre è possibile accedere direttamente ad un elemento di un array, le liste supportano unicamente l’accesso sequenziale. In parole molto semplici, dato ad esempio un array composto da 6 elementi possiamo accedere immediatamente al terzo o al quarto componente della sequenza, mentre nel caso di una lista per accedere a quegli stessi elementi si dovrà passare obbligatoriamente dal primo.

Tali caratteristiche rendono gli array più performanti rispetto alle liste e per questo motivo è stata sviluppata la libreria NumPy che permette di utilizzarli anche in Python. Invocabile tramite la keyword from, tale libreria può essere impiegata in combinazione con il metodo random in questo modo:

# Generare numeri random con NumPy
from numpy import random
x = random.randint(8,21)
print(x)
# possibile output
# 20

L’esempio procedente genera randomicamente un numero intero nell’intervallo compreso tra 8 e 21, volendo invece produrre un valore decimale casuale si dovrà utilizzare il metodo rand() in sostituzione di randint():

# Generare numeri decimali random con NumPy
from numpy import random
x = random.rand()
print(x)
# possibile output
# 0.8798337584569168

Nel caso in cui si voglia produrre un singolo numero decimale casuale dal valore compreso tra 0 e 1 non sarà necessario passare alcun argomento al metodo, in alternativa quest’ultimo accetta come parametro un intero con cui definire il numero di elementi da cui deve essere composto l’array generato in output:

# Generare un array composto da 5 numeri decimali random con NumPy
from numpy import random
x = random.rand(5)
print(x)
# possibile output
# [0.38251211 0.66259408 0.84368404 0.18947054 0.42459943]

E’ inoltre possibile generare randomicamente un array multidimensionale passando al metodo 2 argomenti separati da una virgola: il primo rappresenterà il numero di valori contenuti in ciascun array, il secondo il numero di array che comporrà l’array multidimensionale restituito in output:

# Generare con NumPy un array multidimensionale random
# composto da 5 array contenenti 4 valori ciascuno
from numpy import random
x = random.rand(5,4)
print(x)

L’output prodotto dal codice precedente potrebbe essere simile al seguente:

[[0.84066741 0.22630641 0.6844477 0.68623831]
[0.1804765 0.46100125 0.96735634 0.96621097]
[0.14255415 0.41749025 0.66848924 0.91620726]
[0.11695108 0.24364053 0.47374776 0.14658333]
[0.56971487 0.10945109 0.09462591 0.50644689]]

Volendo invece partire da un array definito a priori ed estrarre un valore casuale da esso è possibile utilizzare il metodo choice() che, appunto, restituisce in output uno qualsiasi dei valori che compongono un array:

# Estrarre un valore casuale da un array
from numpy import random
x = random.choice([4, 7, 12, 13])
print(x)
# possibile output
# 7

Anche in questo caso è possibile generare degli array multidimensionali ricorrendo al metodo size() che accetta come primo parametro il numero di array da produrre e come secondo la quantità di valori per ciascun array:

# Estrazione di valori casuali in un array multidimensionale
from numpy import random
x = random.choice([4, 8, 11, 29], size = (2, 6))
print(x)
# possibile output
# [[29 29 11 4 11 11]
# [8 11 29 8 11 29]]

Chiaramente, nel caso in cui il valore del secondo argomento di size() sia maggiore del numero di valori contenuti nell’array passato come parametro a choice() gli array risultanti presenteranno dei valori ripetuti al loro interno.

Pubblicitร 
Claudio Garau
Claudio Garau
Web developer, programmatore, Database Administrator, Linux Admin, docente e copywriter specializzato in contenuti sulle tecnologie orientate a Web, mobile, Cybersecurity e Digital Marketing per sviluppatori, PA e imprese.

Leggi anche...

Radice quadrata in C: vediamo come calcolarla in diversi modi

La radice quadrata è un'operazione matematica piuttosto comune (in...

Sperimentare la sequenza di Collatz in C++

Vediamo come verificare la congettura di Collatz con C++....

Calcolare la radice quadrata con Python

In Python è possibile calcolare la radice quadrata usando...

12 film che ogni programmatore dovrebbe guardare (per trovare ispirazione e creatività)

Molti ragazzi hanno deciso di intraprendere una carriera da...

Cartonizzare una foto con Python e la libreria OpenCV

La cartoonization è una procedura grafica che consente di...

Creare flowchart (diagrammi di flusso) online: 5 strumenti gratuiti

Hai bisogno di realizzare una flow chart ma non...
Pubblicitร