2017-04-12 72 views
1

我有一個數組,其中包含一組數字n次。例如用n=2隨機分區列表無重複

[0, 1, 2, 3, 4, 0, 1, 2, 3, 4] 

我想是這樣的陣列,其中該分區

  • 的成員包含被從陣列
  • 包含無重複隨機抽取的元素的分區
  • 包含相同數量的元素(最多舍入)k

實施例輸出k=4

[[3,0,2,1], [0,1,4,2], [3,4]] 

無效輸出k=4

[[3,0,2,2], [3,1,4,0], [1,4]] 

(這是一個分區,但分區的第一元件包含重複)

什麼是最Python的方式實現這一目標?

+0

您的分區尚未完善定義。如果k> L/n(其中L是元素的總數),你會做什麼。例如,在你的數組中,你會返回k = 6麼? – Penguino

+0

也許將你的輸入讀入一個'Counter',然後在'Counter'中減去'k'個隨機條目,跟蹤哪一個(這些是你輸出中的子列表)。然後繼續這樣做,直到所有條目都用完爲止。我擔心對於'n'和'k'的某些值以及集合的大小,輸出中的子列表數量可能是隨機的。我不知道這是否會成爲問題,但這是值得關注的 –

回答

2

collections.Counterrandom.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)以最大限度地減少這種可能性。