Shuffling a list of objects
I have a list of objects and I want to shuffle them. I thought I could use the
random.shuffle method, but this seems to fail when the list is of objects. Is there a method for shuffling objects or another way around this?
import random class A: foo = "bar" a1 = a() a2 = a() b = [a1, a2] print(random.shuffle(b))
This will fail.
random.shuffle should work. Here's an example, where the objects are lists:
from random import shuffle x = [[i] for i in range(10)] shuffle(x) # print(x) gives [, , , , , , , , , ] # of course your results will vary
Note that shuffle works in place, and returns None.
Read more… Read less…
As you learned the in-place shuffling was the problem. I also have problem frequently, and often seem to forget how to copy a list, too. Using
sample(a, len(a)) is the solution, using
len(a) as the sample size. See https://docs.python.org/3.6/library/random.html#random.sample for the Python documentation.
Here's a simple version using
random.sample() that returns the shuffled result as a new list.
import random a = range(5) b = random.sample(a, len(a)) print a, b, "two list same:", a == b # print: [0, 1, 2, 3, 4] [2, 1, 3, 4, 0] two list same: False # The function sample allows no duplicates. # Result can be smaller but not larger than the input. a = range(555) b = random.sample(a, len(a)) print "no duplicates:", a == list(set(b)) try: random.sample(a, len(a) + 1) except ValueError as e: print "Nope!", e # print: no duplicates: True # print: Nope! sample larger than population
It took me some time to get that too. But the documentation for shuffle is very clear:
shuffle list x in place; return None.
So you shouldn't
print(random.shuffle(b)). Instead do
random.shuffle(b) and then
#!/usr/bin/python3 import random s=list(range(5)) random.shuffle(s) # << shuffle before print or assignment print(s) # print: [2, 4, 1, 3, 0]
If you happen to be using numpy already (very popular for scientific and financial applications) you can save yourself an import.
import numpy as np np.random.shuffle(b) print(b)
>>> import random >>> a = ['hi','world','cat','dog'] >>> random.shuffle(a,random.random) >>> a ['hi', 'cat', 'dog', 'world']
It works fine for me. Make sure to set the random method.