的collections.Counter
和random.sample
組合可用於:
from collections import Counter
import random
def random_partition(seq, k):
cnts = Counter(seq)
# as long as there are enough items to "sample" take a random sample
while len(cnts) >= k:
sample = random.sample(list(cnts), k)
cnts -= Counter(sample)
yield sample
# Fewer different items than the sample size, just return the unique
# items until the Counter is empty
while cnts:
sample = list(cnts)
cnts -= Counter(sample)
yield sample
這是發電機,其yield
S中的樣本,這樣你就可以簡單地將其轉換爲list
:
>>> l = [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
>>> list(random_partition(l, 4))
[[1, 0, 2, 4], [1, 0, 2, 3], [3, 4]]
>>> list(random_partition(l, 2))
[[1, 0], [3, 0], [1, 4], [2, 3], [4, 2]]
>>> list(random_partition(l, 6))
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
>>> list(random_partition(l, 4))
[[4, 1, 0, 3], [1, 3, 4, 0], [2], [2]]
最後案例顯示,如果函數中的「隨機」部分返回「錯誤」的樣本,則此方法可能會產生奇怪的結果。如果這種情況不應該發生或者至少不經常發生,那麼您需要弄清楚樣本如何加權(例如使用random.choices
)以最大限度地減少這種可能性。
您的分區尚未完善定義。如果k> L/n(其中L是元素的總數),你會做什麼。例如,在你的數組中,你會返回k = 6麼? – Penguino
也許將你的輸入讀入一個'Counter',然後在'Counter'中減去'k'個隨機條目,跟蹤哪一個(這些是你輸出中的子列表)。然後繼續這樣做,直到所有條目都用完爲止。我擔心對於'n'和'k'的某些值以及集合的大小,輸出中的子列表數量可能是隨機的。我不知道這是否會成爲問題,但這是值得關注的 –