6

特定のリスト(またはnumpyの配列)の(連続した)部分のみをシャッフルすることは可能ですか?

これが一般的に不可能である場合、リスト/配列の残りをシャッフルする必要がある間に最初の要素が修正されるという特別なケースはどうですか? たとえば、リスト/配列があります。

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

最初の要素は常に残り、残りの要素は繰り返しシャッフルされます。

考えられる方法の 1 つは、最初にリスト全体をシャッフルしてから最初の要素をチェックし、それが特別な固定要素 (例: None) でない場合は、その位置を特別な要素の位置と交換することです (これにはルックアップが必要になります)。

これを行うためのより良い方法はありますか?

4

4 に答える 4

10

なぜだけではないのですか

import random
rest = to_be_shuffled[1:]
random.shuffle(rest)
shuffled_lst = [to_be_shuffled[0]] + rest
于 2012-07-29T03:03:24.990 に答える
5

numpy 配列はスライス時にデータをコピーしません:

numpy.random.shuffle(a[1:])
于 2012-07-29T04:10:24.933 に答える
4

あなたが求めているものよりも少し一般的なアプローチを実装しようとすることは、興味深く、教育的であると思いました. ここでは、ロックされたインデックスを除外して、インデックスを (リスト自体ではなく) 元のリストにシャッフルし、そのインデックスリストを使用して元のリストから要素を選択します。これはインプレース ソリューションではありませんが、要素を遅延選択できるようにジェネレーターとして実装されています。

改善できる場合は自由に編集してください。

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)
于 2012-07-29T04:09:26.987 に答える
3

標準ライブラリrandomモジュール(にある)からシャッフル関数を取得し、とで指定されLib\random.pyたリストの一部のみをシャッフルするように少し変更しました。これを適切に行います。楽しみ!startstop

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]

1あなたの目的のために、パラメータとしてこの関数を呼び出すstartことはトリックをするべきです。

于 2012-07-29T03:43:01.567 に答える