What Is the Most Pythonic Way to Pop a Random Element from a List

What is the most pythonic way to pop a random element from a list?

What you seem to be up to doesn't look very Pythonic in the first place. You shouldn't remove stuff from the middle of a list, because lists are implemented as arrays in all Python implementations I know of, so this is an O(n) operation.

If you really need this functionality as part of an algorithm, you should check out a data structure like the blist that supports efficient deletion from the middle.

In pure Python, what you can do if you don't need access to the remaining elements is just shuffle the list first and then iterate over it:

lst = [1,2,3]
random.shuffle(lst)
for x in lst:
# ...

If you really need the remainder (which is a bit of a code smell, IMHO), at least you can pop() from the end of the list now (which is fast!):

while lst:
x = lst.pop()
# do something with the element

In general, you can often express your programs more elegantly if you use a more functional style, instead of mutating state (like you do with the list).

How to pop out multiple random elements from a list in Python?

You can shuffle the list and then split it, giving you the sampled elements and the remaining elements.

import numpy as np
list_a = ["a", "b", "c", "d"]
np.random.shuffle(list_a)
list_b, list_a = list_a[:2], list_a[2:]

What is the most Pythonic way to pop a random element from a set in Python3.6+?

The set .pop() method does not accept a parameter, it removes an arbitrary (but not random) set value. https://docs.python.org/3.6/library/stdtypes.html#set.pop

Take a set sample with one element random.sample(s, 1) and use set.remove().

>>> s = set([1,2,3,4,5])
>>> el = random.sample(s, 1)[0]
>>> s.remove(el)
>>> print(s)
{1, 3, 4, 5}

The random.choice does not work because sets are not indexed.

>>> random.choice(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/random.py", line 256, in choice
return seq[i]

How can I randomly select an item from a 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 secrets.choice():

import secrets

foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))

secrets is new in Python 3.6. On older versions of Python you can use the random.SystemRandom class:

import random

secure_random = random.SystemRandom()
print(secure_random.choice(foo))

Is there a simple way to randomly pick from a list with the exception of one element?

Maybe you could use random.sample:

Return a k length list of unique elements chosen from the population
sequence or set. Used for random sampling without replacement.

>>> import random
>>> l = ['a', 'b', 'c', 'd']
>>> random.sample(l, 3) # Pick 3 random elements without replacement from l
['c', 'd', 'a']

How can you select a random element from a list, and have it be removed?

Firstly, if you want it removed because you want to do this again and again, you might want to use random.shuffle() in the random module.

random.choice() picks one, but does not remove it.

Otherwise, try:

import random

# this will choose one and remove it
def choose_and_remove( items ):
# pick an item index
if items:
index = random.randrange( len(items) )
return items.pop(index)
# nothing left!
return None

Most pythonic way to select at random an element in a list with conditions

If your elements are unique you can use the set difference. (Convert list1 to a set and remove the elements from list2). Then draw a random sample.

random.choice(list(set(list1).difference(list2)))

Randomly remove 'x' elements from a list

You can use random.sample like this:

import random

a = [1,2,3,4,5,6,7,8,9,10]

no_elements_to_delete = len(a) // 4
no_elements_to_keep = len(a) - no_elements_to_delete
b = set(random.sample(a, no_elements_to_keep)) # the `if i in b` on the next line would benefit from b being a set for large lists
b = [i for i in a if i in b] # you need this to restore the order
print(len(a)) # 10
print(b) # [1, 2, 3, 4, 5, 8, 9, 10]
print(len(b)) # 8

Two notes on the above.

  1. You are not modifying the original list in place but you could.
  2. You are not actually deleting elements but rather keeping elements but it is the same thing (you just have to adjust the ratios)
  3. The drawback is the list-comprehension that restores the order of the elements

As @koalo says in the comments the above will not work properly if the elements in the original list are not unique. I could easily fix that but then my answer would be identical to the one posted by@JohnColeman. So if that might be the case just use his instead.

How to remove a random element from a list and add it to another list in python

winner.append(list.pop(random.randrange(0,len(list))))

To break this down:

random.randrange(0,len(list)) 

will generate a random number between zero and the length of your list inclusive. This will generate a random index in your list that you can reference.

list.pop(i)

This will remove the item at the specified index (i) from your list.

winner.append(x)

This will add an item (x) to the end of the winner list. If you want to add the item at a specific index, you can use

winner.insert(i,x) 

with i being the index to insert at and x being the value to insert.

If you want more information, a good reference is the python docs on data structures:
https://docs.python.org/2/tutorial/datastructures.html



Related Topics



Leave a reply



Submit