2017-04-12 11 views
1

Ich habe ein Array, das jeweils eine Reihe von Zahlen n mal enthält. Beispiel mit n=2:nach dem Zufallsprinzip Partition Liste ohne Duplikate

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

Was würde Ich mag eine Partition dieser Anordnung, bei der die Mitglieder der Trennwand

  • Elemente enthalten, die zufällig aus dem Array
  • enthalten keine Duplikate erstellt werden
  • enthalten die gleiche Anzahl von Elementen (bis zur Rundung) k

Beispielausgabe für k=4:

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

Ungültige Ausgang für k=4:

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

(dies ist eine Partition, aber das erste Element der Partition enthält Duplikate)

Was die pythonic Weg, das zu erreichen?

+0

Ihre Partitionierung ist noch nicht klar definiert. Was tun Sie in dem Fall, dass k> L/n (wobei L die Gesamtzahl der Elemente ist). Zum Beispiel, in Ihrem Array, was würden Sie für k = 6 zurückgeben? – Penguino

+0

Vielleicht lesen Sie Ihre Eingabe in einen 'Counter', dekrementieren Sie dann' k' zufällige Einträge in diesem 'Counter', und verfolgen Sie welche (das sind die Unterlisten in Ihrer Ausgabe). Dann mach das solange, bis alle Einträge erschöpft sind. Ich wäre besorgt, dass für einige Werte von "n" und "k" und die Größe des Satzes die Anzahl der Unterlisten in Ihrer Ausgabe zufällig sein könnte. Ich weiß nicht, ob das ein Problem sein würde, aber es ist etwas, das man beobachten kann –

Antwort

2

Eine Kombination aus collections.Counter und random.sample verwendet werden können:

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 

Dies ist ein Generator, dass yield s die Proben, so dass Sie sie einfach an einen list werfen können:

>>> 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]] 

Die letzte Der Fall zeigt, dass diese Methode seltsame Ergebnisse liefern kann, wenn der "zufällige" Teil in der Funktion die "falschen" Proben zurückgibt. Wenn das nicht oder nicht oft genug passiert, müssen Sie herausfinden, wie die Stichproben gewichtet werden können (zum Beispiel mit random.choices), um diese Möglichkeit zu minimieren.

Verwandte Themen