cycla
cycla

Reputation: 147

How can I shuffle the list with constraints(related to the index of each elements)

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

Answers (2)

wjandrea
wjandrea

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

Tim Roberts
Tim Roberts

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

Related Questions