How to randomly select an item from a list?

后端 未结 15 1322
伪装坚强ぢ
伪装坚强ぢ 2020-11-21 07:49

Assume I have the following list:

foo = [\'a\', \'b\', \'c\', \'d\', \'e\']

What is the simplest way to retrieve an item at random from thi

相关标签:
15条回答
  • 2020-11-21 08:12

    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:)

    0 讨论(0)
  • 2020-11-21 08:13

    If you also need the index, use random.randrange

    from random import randrange
    random_index = randrange(len(foo))
    print(foo[random_index])
    
    0 讨论(0)
  • 2020-11-21 08:13

    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.

    0 讨论(0)
  • 2020-11-21 08:18

    This may already be an answer but you could use random.shuffle. Example:

    import random
    foo = ['a', 'b', 'c', 'd', 'e']
    random.shuffle(foo)
    
    0 讨论(0)
  • 2020-11-21 08:19

    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]
    

    EDIT: Pythonic One-Liner

    If you want a more pythonic one-liner for selecting multiple items, you can use unpacking.

    import random
    first_random_item, second_random_item = random.sample(group_of_items, 2)
    
    0 讨论(0)
  • 2020-11-21 08:21

    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 secrets.choice from the standard library (New in Python 3.6.):

    >>> from secrets import choice         # Python 3 only
    >>> choice(list('abcde'))
    'c'
    

    The above is equivalent to my former recommendation, using a SystemRandom object from the random module with the choice method - available earlier in Python 2:

    >>> import random                      # Python 2 compatible
    >>> 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')
    

    A comment:

    This is not about whether random.choice is truly random or not. If you fix the seed, you will get the reproducible results -- and that's what seed is designed for. You can pass a seed to SystemRandom, too. sr = random.SystemRandom(42)

    Well, yes you can pass it a "seed" argument, but you'll see that the SystemRandom object simply ignores it:

    def seed(self, *args, **kwds):
        "Stub method.  Not used for a system random number generator."
        return None
    
    0 讨论(0)
提交回复
热议问题