Assume I have the following list:
foo = ['a', 'b', 'c', 'd', 'e']
What is the simplest way to retrieve an item at random from this list?
Use random.choice
:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
For cryptographically secure random choices (e.g. for generating a passphrase from a wordlist), use random.SystemRandom
class:
import random
foo = ['battery', 'correct', 'horse', 'staple']
secure_random = random.SystemRandom()
print(secure_random.choice(foo))
Standard pseudo-random generators are not suitable for security/cryptographic purposes.
refJeff Xiao 2019-01-30 19:46
If you want to randomly select more than one item from a list, or select an item from a set, I'd recommend using random.sample
instead.
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]
If you're only pulling a single item from a list though, choice is less clunky, as using sample would have the syntax random.sample(some_list, 1)[0]
instead of random.choice(some_list)
.
Unfortunately though, choice only works for a single output from sequences (such as lists or tuples). Though random.choice(tuple(some_set))
may be an option for getting a single item from a set.
EDIT: Using Secrets
As many have pointed out, if you require more secure pseudorandom samples, you should use the secrets module:
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]
If you also need the index, use random.randrange
from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])
As of Python 3.6 you can use the secrets
module, which is preferable to the random
module for cryptography or security uses.
To print a random element from a list:
import secrets
foo = ['a', 'b', 'c', 'd', 'e']
print(secrets.choice(foo))
To print a random index:
print(secrets.randbelow(len(foo)))
For details, see PEP 506.
I propose a script for removing randomly picked up items off a list until it is empty:
Maintain a set
and remove randomly picked up element (with choice
) until list is empty.
s=set(range(1,6))
import random
while len(s)>0:
s.remove(random.choice(list(s)))
print(s)
Three runs give three different answers:
>>>
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
the list
once and either iterate it or pop it to produce results. Either would result in a perfectly adequate "select randomly with no repeats" stream, it's just that the randomness would be introduced at the beginning - ShadowRanger 2015-12-25 03:23
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
is with replacement while random.sample
is without replacement - CentAu 2018-03-05 23:43
if you need the index just use:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print int(random.random() * len(foo))
print foo[int(random.random() * len(foo))]
random.choice does the same:)
random.choice(self, seq)
is return seq[int(self.random() * len(seq))]
- wim 2013-04-12 04:56
randrange()
which means e.g. random.SystemRandom().randrange(3<<51)
exhibits significant bias. Sigh...tc. 2013-04-13 23:55
float
(an IEEE double) can only take a finite number of values in [0,1). Random.random()
generates its output in the traditional way: pick a random integer in [0, 2**53)
and divide by 2**53
(53 is the number of bits in a double). So random()
returns 2**53 equiprobable doubles, and you can divide this evenly into N outputs only if N is a power of 2. The bias is small for small N, but see collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common()
. (Java's Random.nextInt() avoids such bias. - tc. 2014-01-18 16:37
2**40
, (which is 1099511627776), would be small enough for the bias to not matter in practice? This should really be pointed out in the documentation, because if somebody is not meticulous, they might not expect problems to come from this part of their code - Evgeni Sergeev 2015-05-29 01:28
random
uses getrandbits
to get an adequate number of bits to generate a result for larger randrange
s (random.choice
is also using that). This is true on both 2.7 and 3.5. It only uses self.random() * len(seq)
when getrandbits
is not available. It's not doing the stupid thing you think it is - ShadowRanger 2015-12-25 03:32
This is the code with a variable that defines the random index:
import random
foo = ['a', 'b', 'c', 'd', 'e']
randomindex = random.randint(0,len(foo)-1)
print (foo[randomindex])
## print (randomindex)
This is the code without the variable:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print (foo[random.randint(0,len(foo)-1)])
And this is the code in the shortest and smartest way to do it:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
(python 2.7)
How to randomly select an item from a list?
Assume I have the following list:
foo = ['a', 'b', 'c', 'd', 'e']
What is the simplest way to retrieve an item at random from this list?
If you want close to truly random, then I suggest using a SystemRandom
object from the random
module with the choice
method:
>>> import random
>>> sr = random.SystemRandom()
>>> foo = list('abcde')
>>> foo
['a', 'b', 'c', 'd', 'e']
And now:
>>> 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'
If you want a deterministic pseudorandom selection, use the choice
function (which is actually a bound method on a Random
object):
>>> random.choice
<bound method Random.choice of <random.Random object at 0x800c1034>>
It seems random, but it's actually not, which we can see if we reseed it repeatedly:
>>> 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')
numpy
solution: numpy.random.choice
For this question, it works the same as the accepted answer (import random; random.choice()
), but I added it because the programmer may have imported numpy
already (like me)
& also there are some differences between the two methods that may concern your actual use case.
import numpy as np
np.random.choice(foo) # randomly selects a single item
For reproducibility, you can do:
np.random.seed(123)
np.random.choice(foo) # first call will always return 'c'
For samples of one or more items, returned as an array
, pass the size
argument:
np.random.choice(foo, 5) # sample with replacement (default)
np.random.choice(foo, 5, False) # sample without replacement
We can also do this using 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()
and random.randrange()
- alexis 2016-03-19 15:10
None
just kicks the can to some random later point where the invalid "element" triggers an exception; or worse yet, you get an incorrect program instead of an exception, and you don't even know it - alexis 2017-09-05 09:27
The following code demonstrates if you need to produce the same items. You can also specify how many samples you want to extract.
The sample
method returns a new list containing elements from the population while leaving the original population unchanged. The resulting list is in selection order so that all sub-slices will also be valid random samples.
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']
One easy solution if you are looking for something like this:
from random import *
library = ["New York", "Berlin", "Rome"]
for x in range (10):
i = randrange(0,3)
print(library[i])
I did this to get it to work:
import random
pick = ['Random','Random1','Random2','Random3']
print (pick[int(random.random() * len(pick))])
import random_necessary
pick = ['Miss','Mrs','MiSs','Miss']
print pick [int(random_necessary.random_necessary() * len(pick))]
I hope that you find this solution helpful.
random.choice(foo)
return two different results - Eduardo Pignatelli 2018-12-07 17:13