質問をまとめるのに苦労しているので、例を挙げて説明します。
x = ['abc', 'c', 'w', 't', '3']
a, b = random_split(x, 3) # first list should be length 3
# e.g. a => ['abc', 'w', 't']
# e.g. b => ['c', '3']
元の順序を維持しながら、リストを 2 つのランダム サンプルに分割する簡単な方法はありますか?
編集: random.sample を使用して並べ替えることができることは知っていますが、簡単でシンプルな 1 行の方法を望んでいました。
編集 2:別の解決策があります。改善できるかどうかを確認してください。
def random_split(l, a_size):
a, b = [], []
m = len(l)
which = ([a] * a_size) + ([b] * (m - a_size))
random.shuffle(which)
for array, sample in zip(which, l):
array.append(sample)
return a, b
編集 3:並べ替えを回避する上での私の懸念は、最良のシナリオではO(N*log(N))
. O(N)
残念ながら、これまでに投稿されたソリューションのどれも実際に達成することはできませO(N)
んが、少し考えた後、@ PedroWerneckのパフォーマンスの答えに匹敵する機能を見つけました。ただし、それが本当にランダムかどうかは 100% 確信が持てません。
def random_split(items, size):
n = len(items)
a, b = [], []
for item in items:
if size > 0 and random.random() < float(size)/n:
b.append(item)
size -= 1
else:
a.append(item)
n -= 1
return a, b