Respostas:
Usar random.choice()
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
Para escolhas aleatórias seguras criptograficamente (por exemplo, para gerar uma frase secreta a partir de uma lista de palavras), usesecrets.choice()
import secrets
foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))
secrets
é novo no Python 3.6, nas versões mais antigas do Python você pode usar a random.SystemRandom
classe:
import random
secure_random = random.SystemRandom()
print(secure_random.choice(foo))
random.sample(lst, n)
Se você deseja selecionar aleatoriamente mais de um item de uma lista ou selecionar um item de um conjunto, recomendo o uso random.sample
.
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]
Porém, se você estiver apenas puxando um único item de uma lista, a escolha será menos desajeitada, pois o uso de amostra teria a sintaxe em random.sample(some_list, 1)[0]
vez de random.choice(some_list)
.
Infelizmente, porém, a escolha funciona apenas para uma única saída de seqüências (como listas ou tuplas). Embora random.choice(tuple(some_set))
possa ser uma opção para obter um único item de um conjunto.
EDIT: Usando segredos
Como muitos apontaram, se você precisar de amostras pseudo-aleatórias mais seguras, use o módulo 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 desejar uma linha única mais pitônica para selecionar vários itens, você pode usar a descompactação.
import random
first_random_item, second_random_item = random.sample(group_of_items, 2)
secrets
módulo BTW foi adicionado à biblioteca padrão do Python na versão 3.6 python.org/dev/peps/pep-0506
Se você também precisar do índice, use random.randrange
from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])
No Python 3.6, você pode usar o secrets
módulo, que é preferível ao random
módulo para criptografia ou segurança.
Para imprimir um elemento aleatório de uma lista:
import secrets
foo = ['a', 'b', 'c', 'd', 'e']
print(secrets.choice(foo))
Para imprimir um índice aleatório:
print(secrets.randbelow(len(foo)))
Para detalhes, consulte PEP 506 .
Proponho um script para remover itens coletados aleatoriamente de uma lista até que ela fique vazia:
Mantenha um set
e remova o elemento selecionado aleatoriamente (com choice
) até que a lista esteja vazia.
s=set(range(1,6))
import random
while len(s)>0:
s.remove(random.choice(list(s)))
print(s)
Três execuções fornecem três respostas diferentes:
>>>
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.shuffle
a list
uma vez e quer iterate-lo ou colocá-la para produzir resultados. Ou resultaria em um fluxo "selecionar aleatoriamente sem repetições" perfeitamente adequado, mas a aleatoriedade seria introduzida no início.
foo = ['a', 'b', 'c', 'd', 'e']
number_of_samples = 1
No python 2:
random_items = random.sample(population=foo, k=number_of_samples)
No python 3:
random_items = random.choices(population=foo, k=number_of_samples)
random.choices
está com substituição enquanto random.sample
está sem substituição.
numpy
solução: numpy.random.choice
Para esta pergunta, funciona da mesma forma que a resposta aceita ( import random; random.choice()
), mas eu a adicionei porque o programador já pode ter importado numpy
(como eu) e também existem algumas diferenças entre os dois métodos que podem estar relacionados ao seu caso de uso real.
import numpy as np
np.random.choice(foo) # randomly selects a single item
Para reprodutibilidade, você pode fazer:
np.random.seed(123)
np.random.choice(foo) # first call will always return 'c'
Para amostras de um ou mais itens , retornados como um array
, passe o size
argumento:
np.random.choice(foo, 5) # sample with replacement (default)
np.random.choice(foo, 5, False) # sample without replacement
Como selecionar aleatoriamente um item de uma lista?
Suponha que eu tenha a seguinte lista:
foo = ['a', 'b', 'c', 'd', 'e']
Qual é a maneira mais simples de recuperar um item aleatoriamente dessa lista?
Se você quiser quase aleatoriamente , sugiro secrets.choice
da biblioteca padrão (Novo no Python 3.6.):
>>> from secrets import choice # Python 3 only
>>> choice(list('abcde'))
'c'
O acima é equivalente à minha recomendação anterior, usando um SystemRandom
objeto do random
módulo com o choice
método - disponível anteriormente no Python 2:
>>> import random # Python 2 compatible
>>> sr = random.SystemRandom()
>>> foo = list('abcde')
>>> foo
['a', 'b', 'c', 'd', 'e']
E agora:
>>> 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 você deseja uma seleção pseudo-aleatória determinística, use a choice
função (que na verdade é um método vinculado a um Random
objeto):
>>> random.choice
<bound method Random.choice of <random.Random object at 0x800c1034>>
Parece aleatório, mas na verdade não é, o que podemos ver se o repetirmos novamente:
>>> 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')
Não se trata de random.choice ser verdadeiramente aleatório ou não. Se você consertar a semente, obterá resultados reproduzíveis - e é para isso que a semente é projetada. Você também pode passar uma semente para o SystemRandom.
sr = random.SystemRandom(42)
Bem, sim, você pode passar um argumento "semente", mas verá que o SystemRandom
objeto simplesmente o ignora :
def seed(self, *args, **kwds):
"Stub method. Not used for a system random number generator."
return None
se você precisar do índice, use:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print int(random.random() * len(foo))
print foo[int(random.random() * len(foo))]
random.choice faz o mesmo :)
random.choice(self, seq)
is return seq[int(self.random() * len(seq))]
.
randrange()
qual significa, por exemplo, random.SystemRandom().randrange(3<<51)
exibe viés significativo. Suspiro ...
float
(um duplo IEEE) só pode receber um número finito de valores em [0,1). Random.random()
gera sua saída da maneira tradicional: escolha um número inteiro aleatório [0, 2**53)
e divida por 2**53
(53 é o número de bits em um dobro). Portanto, random()
retorna 2 ** 53 duplos equiprobáveis, e você pode dividir isso uniformemente em saídas N apenas se N for uma potência de 2. O viés é pequeno para N pequeno, mas veja collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common()
. (O Random.nextInt () de Java evita esse viés.)
2**40
(1099511627776) seria pequeno o suficiente para que o viés não importasse na prática? Isso realmente deve ser apontado na documentação, porque se alguém não for meticuloso, talvez não espere que surjam problemas dessa parte do código.
random
usa getrandbits
para obter um número adequado de bits para gerar um resultado para randrange
s maiores ( random.choice
também está usando isso). Isso é verdade tanto no 2.7 quanto no 3.5. Ele usa apenas self.random() * len(seq)
quando getrandbits
não está disponível. Não está fazendo a coisa estúpida que você pensa que é.
Este é o código com uma variável que define o índice aleatório:
import random
foo = ['a', 'b', 'c', 'd', 'e']
randomindex = random.randint(0,len(foo)-1)
print (foo[randomindex])
## print (randomindex)
Este é o código sem a variável:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print (foo[random.randint(0,len(foo)-1)])
E este é o código da maneira mais rápida e inteligente possível:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
(python 2.7)
O código a seguir demonstra se você precisa produzir os mesmos itens. Você também pode especificar quantas amostras deseja extrair.
O sample
método retorna uma nova lista contendo elementos da população, mantendo inalterada a população original. A lista resultante está na ordem de seleção, para que todas as sub-fatias também sejam amostras aleatórias válidas.
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]
Duplicado de https://stackoverflow.com/a/49682832/4383027
Também podemos fazer isso 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()
?
None
apenas chuta a lata para algum ponto posterior aleatório, onde o "elemento" inválido dispara uma exceção; ou pior ainda, você obtém um programa incorreto em vez de uma exceção e nem o conhece.
Você poderia apenas:
from random import randint
foo = ["a", "b", "c", "d", "e"]
print(foo[randint(0,4)])
random.choice(foo)
retorno consecutivas tem dois resultados diferentes?