Reputation: 147
For example, there is a list, [1,2,3]
with constraint such that each elements of the shuffled list should not overlap with the location of the previous elements.
To make the explanation clear, let's say the previous list was [1,2,3]
, but after shuffling it becomes [1,3,2]
. For this case, since 1
is the first element of the both lists, this does not satisfy the constraint. The outputs that satisfy that constraint would be, [2,3,1]
and [3,1,2]
.
Is there a way to make this constraint before shuffling the list?
Thanks in advance.
Upvotes: 1
Views: 225
Reputation: 32997
You can accomplish this by rotating the list. For example, the rotations of [1, 2, 3]
are [3, 1, 2]
and [2, 3, 1]
.
Note that for lengths > 3, the rotations will be a subset of all possible shuffles that fit your constraints, but if I understand correctly, that works for you. For example, with input [1, 2, 3, 4]
, [4, 3, 2, 1]
is a valid output, but not a rotation.
collections.deque
makes it easy to rotate, plus it's optimized for rotation.
random.randrange()
can be used to randomize the rotation count.
import random
import collections
def random_rotation(lst):
"""
Rotate a list by a random amount.
Similar to "random.shuffle()", but ensures that all elements will move.
"""
n = random.randrange(1, len(lst))
d = collections.deque(lst)
d.rotate(n)
lst[:] = d # Overwrite
L = [1, 2, 3, 4]
random_rotation(L)
print(L)
Example output:
[2, 3, 4, 1]
Upvotes: 1
Reputation: 54718
Based on your spec, what you're asking for is just all possible rotations of the list. For example:
def rotations(lst):
for i in range(len(lst)):
print(lst)
lst.append(lst.pop(0))
Upvotes: 0