Risposte:
Uso random.choice()
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
Per scelte casuali crittograficamente sicure (ad esempio per generare una passphrase da un elenco di parole) utilizzaresecrets.choice()
import secrets
foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))
secretsè una novità di Python 3.6, nelle versioni precedenti di Python è possibile utilizzare la random.SystemRandomclasse:
import random
secure_random = random.SystemRandom()
print(secure_random.choice(foo))
random.sample(lst, n)
Se si desidera selezionare casualmente più di un elemento da un elenco o selezionare un elemento da un set, si consiglia di utilizzare random.sampleinvece.
import random
group_of_items = {1, 2, 3, 4} # a sequence or set will work here.
num_to_select = 2 # set the number to select here.
list_of_random_items = random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1]
Se stai solo estraendo un singolo elemento da un elenco, la scelta è meno ingombrante, poiché l'utilizzo del campione avrebbe la sintassi random.sample(some_list, 1)[0]anziché random.choice(some_list).
Sfortunatamente, la scelta funziona solo per un singolo output delle sequenze (come elenchi o tuple). Sebbene random.choice(tuple(some_set))possa essere un'opzione per ottenere un singolo oggetto da un set.
EDIT: utilizzo dei segreti
Come molti hanno sottolineato, se hai bisogno di campioni pseudocasuali più sicuri, dovresti usare il modulo secrets:
import secrets # imports secure module.
secure_random = secrets.SystemRandom() # creates a secure random object.
group_of_items = {1, 2, 3, 4} # a sequence or set will work here.
num_to_select = 2 # set the number to select here.
list_of_random_items = secure_random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1]
EDIT: Pythonic One-Liner
Se si desidera un one-liner più pitone per la selezione di più elementi, è possibile utilizzare il disimballaggio.
import random
first_random_item, second_random_item = random.sample(group_of_items, 2)
secretsmodulo BTW è stato aggiunto alla libreria standard Python nella versione 3.6 python.org/dev/peps/pep-0506
Se è necessario anche l'indice, utilizzare random.randrange
from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])
A partire da Python 3.6 è possibile utilizzare il secretsmodulo, che è preferibile al randommodulo per scopi di crittografia o sicurezza.
Per stampare un elemento casuale da un elenco:
import secrets
foo = ['a', 'b', 'c', 'd', 'e']
print(secrets.choice(foo))
Per stampare un indice casuale:
print(secrets.randbelow(len(foo)))
Per i dettagli, vedere PEP 506 .
Propongo uno script per la rimozione casuale degli elementi raccolti da un elenco fino a quando non è vuoto:
Mantieni ae setrimuovi l'elemento prelevato casualmente (con choice) fino a quando l'elenco è vuoto.
s=set(range(1,6))
import random
while len(s)>0:
s.remove(random.choice(list(s)))
print(s)
Tre prove danno tre risposte diverse:
>>>
set([1, 3, 4, 5])
set([3, 4, 5])
set([3, 4])
set([4])
set([])
>>>
set([1, 2, 3, 5])
set([2, 3, 5])
set([2, 3])
set([2])
set([])
>>>
set([1, 2, 3, 5])
set([1, 2, 3])
set([1, 2])
set([1])
set([])
random.shuffleil listtempo e sia iterare o pop per produrre risultati. O si tradurrebbe in un flusso "seleziona in modo casuale senza ripetizioni" perfettamente adeguato, è solo che la casualità verrebbe introdotta all'inizio.
foo = ['a', 'b', 'c', 'd', 'e']
number_of_samples = 1
In Python 2:
random_items = random.sample(population=foo, k=number_of_samples)
In Python 3:
random_items = random.choices(population=foo, k=number_of_samples)
random.choicesè con la sostituzione mentre random.sampleè senza sostituzione.
numpy soluzione: numpy.random.choice
Per questa domanda, funziona come la risposta accettata ( import random; random.choice()), ma l'ho aggiunta perché il programmatore potrebbe aver numpygià importato (come me) e inoltre ci sono alcune differenze tra i due metodi che possono riguardare il tuo caso d'uso reale.
import numpy as np
np.random.choice(foo) # randomly selects a single item
Per la riproducibilità, puoi fare:
np.random.seed(123)
np.random.choice(foo) # first call will always return 'c'
Per i campioni di uno o più articoli , restituiti come an array, passare l' sizeargomento:
np.random.choice(foo, 5) # sample with replacement (default)
np.random.choice(foo, 5, False) # sample without replacement
Come selezionare casualmente un elemento da un elenco?
Supponiamo di avere il seguente elenco:
foo = ['a', 'b', 'c', 'd', 'e']Qual è il modo più semplice per recuperare un elemento a caso da questo elenco?
Se vuoi un risultato quasi casuale , suggerisco secrets.choicedalla libreria standard (Novità in Python 3.6.):
>>> from secrets import choice # Python 3 only
>>> choice(list('abcde'))
'c'
Quanto sopra equivale alla mia precedente raccomandazione, usando un SystemRandomoggetto dal randommodulo con il choicemetodo - disponibile in precedenza in Python 2:
>>> import random # Python 2 compatible
>>> sr = random.SystemRandom()
>>> foo = list('abcde')
>>> foo
['a', 'b', 'c', 'd', 'e']
E adesso:
>>> sr.choice(foo)
'd'
>>> sr.choice(foo)
'e'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'b'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'c'
>>> sr.choice(foo)
'c'
Se si desidera una selezione pseudocasuale deterministica, utilizzare la choicefunzione (che in realtà è un metodo associato su un Randomoggetto):
>>> random.choice
<bound method Random.choice of <random.Random object at 0x800c1034>>
Sembra casuale, ma in realtà non lo è, che possiamo vedere se lo abbiamo ridimensionato ripetutamente:
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
Non si tratta di stabilire se random.choice sia davvero casuale. Se aggiusti il seme, otterrai risultati riproducibili - ed è per questo che è progettato il seme. Puoi anche passare un seme a SystemRandom.
sr = random.SystemRandom(42)
Bene, sì, puoi passare un argomento "seed", ma vedrai che l' SystemRandomoggetto semplicemente lo ignora :
def seed(self, *args, **kwds):
"Stub method. Not used for a system random number generator."
return None
se hai bisogno dell'indice usa solo:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print int(random.random() * len(foo))
print foo[int(random.random() * len(foo))]
random.choice fa lo stesso :)
random.choice(self, seq)is return seq[int(self.random() * len(seq))].
randrange()che significa ad esempio che random.SystemRandom().randrange(3<<51)mostra un pregiudizio significativo. Sigh ...
float(un doppio IEEE) può prendere solo un numero finito di valori in [0,1). Random.random()genera il suo output nel modo tradizionale: scegli un numero intero casuale [0, 2**53)e dividi per 2**53(53 è il numero di bit in un doppio). Quindi random()restituisce 2 ** 53 doppi equiprobabili, e puoi dividerlo uniformemente in N output solo se N è una potenza di 2. Il bias è piccolo per N piccolo, ma vedi collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common(). (Java's Random.nextInt () evita tale distorsione.)
2**40((che è 1099511627776), sarebbe abbastanza piccolo da non dare importanza al pregiudizio nella pratica? Questo dovrebbe davvero essere sottolineato nella documentazione, perché se qualcuno non è meticoloso, potrebbero non aspettarsi che i problemi provengano da questa parte del loro codice.
randomutilizza getrandbitsper ottenere un numero adeguato di bit per generare un risultato per randranges più grandi (lo random.choicesta anche usando). Questo vale sia per 2.7 che per 3.5. Utilizza solo self.random() * len(seq)quando getrandbitsnon è disponibile. Non sta facendo la cosa stupida che pensi che sia.
Questo è il codice con una variabile che definisce l'indice casuale:
import random
foo = ['a', 'b', 'c', 'd', 'e']
randomindex = random.randint(0,len(foo)-1)
print (foo[randomindex])
## print (randomindex)
Questo è il codice senza la variabile:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print (foo[random.randint(0,len(foo)-1)])
E questo è il codice nel modo più breve e intelligente per farlo:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
(python 2.7)
Il seguente codice dimostra se è necessario produrre gli stessi articoli. Puoi anche specificare quanti campioni vuoi estrarre.
Il samplemetodo restituisce un nuovo elenco contenente elementi della popolazione lasciando invariata la popolazione originale. L'elenco risultante è in ordine di selezione in modo che anche tutti i sottotitoli siano campioni casuali validi.
import random as random
random.seed(0) # don't use seed function, if you want different results in each run
print(random.sample(foo,3)) # 3 is the number of sample you want to retrieve
Output:['d', 'e', 'a']
import random
my_list = [1, 2, 3, 4, 5]
num_selections = 2
new_list = random.sample(my_list, num_selections)
randIndex = random.sample(range(len(my_list)), n_selections)
randIndex.sort()
new_list = [my_list[i] for i in randIndex]
Duplicato di https://stackoverflow.com/a/49682832/4383027
Possiamo anche farlo usando randint.
from random import randint
l= ['a','b','c']
def get_rand_element(l):
if l:
return l[randint(0,len(l)-1)]
else:
return None
get_rand_element(l)
random.choice()e random.randrange()?
Nonedà dei calci alla lattina in un punto successivo casuale in cui l '"elemento" non valido innesca un'eccezione; o peggio ancora, ottieni un programma errato invece di un'eccezione e non lo sai nemmeno.
Potresti semplicemente:
from random import randint
foo = ["a", "b", "c", "d", "e"]
print(foo[randint(0,4)])
random.choice(foo)ritorno ha due risultati diversi?