Fix first item, shuffle remaining list / array items

Is it possible to shuffle only the (continuous) part of a given list (or an array in numpy)?

If this is not possible at all, what about the special case where the first element is fixed and the rest of the list / array needs to be shuffled? For example, I have a list / array:

to_be_shuffled = [None, 'a', 'b', 'c', 'd', ...]

where the first element should always remain, while the rest will move repeatedly.

One possible way is to first shuffle the entire list, and then check the first element if it is not a special fixed element (for example None), and then change its position to the position of a special element (which then requires a search).

Is there a better way to do this?

+5
source share
4 answers

numpy arrays do not copy slicing data:

numpy.random.shuffle(a[1:])
+5
source

Why not just

import random
rest = to_be_shuffled[1:]
random.shuffle(rest)
shuffled_lst = [to_be_shuffled[0]] + rest
+9
source

, , , , . ( ), , . , , .

, .

import random

def partial_shuf(input_list, fixed_indices):
    """Given an input_list, yield elements from that list in random order
    except where elements indices are in fixed_indices."""
    fixed_indices = sorted(set(i for i in fixed_indices if i < len(input_list)))
    i = 0
    for fixed in fixed_indices:
        aslice = range(i, fixed)
        i = 1 + fixed
        random.shuffle(aslice)
        for j in aslice:
            yield input_list[j]
        yield input_list[fixed]
    aslice = range(i, len(input_list))
    random.shuffle(aslice)
    for j in aslice:
        yield input_list[j]

print '\n'.join(' '.join((str(i), str(n))) for i, n in enumerate(partial_shuf(range(4, 36), [0, 4, 9, 17, 25, 40])))

assert sorted(partial_shuf(range(4, 36), [0, 4, 9, 17, 25, 40])) == range(4, 36)
+4

random ( Lib\random.py) , , start stop. . !

from random import randint

def shuffle(x, start=0, stop=None):
    if stop is None:
        stop = len(x)

    for i in reversed(range(start + 1, stop)):
        # pick an element in x[start: i+1] with which to exchange x[i]
        j = randint(start, i)
        x[i], x[j] = x[j], x[i]

For your purposes, calling this function using 1as a parameter startshould do the trick.

+3
source

All Articles