Advertisement
Advertisement


Shuffling a list of objects


Question

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.

2019/10/15
1
789
10/15/2019 1:57:48 AM

Accepted Answer

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  [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]
# of course your results will vary

Note that shuffle works in place, and returns None.

2019/10/15
1265
10/15/2019 1:58:12 AM

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
2017/10/25

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 print(b).

2019/10/15

#!/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]
2010/12/04

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)

http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html

2015/02/28

>>> 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.

2009/06/10

Source: https://stackoverflow.com/questions/976882
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]