Consider random.shuffle
on a list-of-objects (i.e. not primitive types like int).
I'm talking about any general object; the numbers in the following are only an example.
Since random.shuffle acts in-place and returns None, that makes it slightly clunky to shuffle a slice or subset of that list. For a slice (or subset), is there a better way than taking the slice (or a deepcopy), shuffling it, then overwriting the original list slice with the result? i.e. as follows:
import copy
import random
class SomeNumber(object): # just a stupid class to illustrate the point
def __init__(self, n):
self.n = n
def __repr__(self):
return str(self.n)
ll = [ SomeNumber(i) for i in range(6) ]
# [0, 1, 2, 3, 4, 5]
# Say we want to shuffle slice 2:end
#ld = copy.deepcopy(ll[2:])
ld = ll[2:]
# [2, 3, 4, 5]
random.shuffle(ld)
# [3, 2, 4, 5]
# ll didn't get shuffled though, so must overwrite the original slice...
ll[2:] = ld
# [0, 1, 5, 3, 4, 2]
del ld
Consider also the more general case where I might want to pass a boolean vector of which elements are to be included in the shuffle. Then extract that subset, shuffle it and reinsert it. Can you find a good idiom?
PS @ReutSharabani suggests something like:
def partial_shuffle(lst, imin, imax):
lst[imin:imax] = sorted(lst[imin:imax], key=lambda x: random.random())
return lst