2017-07-18 2 views
4

Code:Randomly ein anderes Paar von Elementen aus einer Liste auswählen

import random 

x = ['A','B','C','D','E','F', 
    'G','H','I','J','K','L', 
    'M','N','O','P','Q','R', 
    'S','T','U','V','W','X', 
    'Y','Z'] 

y1 = random.sample(x, 2) 
y2 = random.sample(x, 2) 
y3 = random.sample(x, 2) 
y4 = random.sample(x, 2) 
y5 = random.sample(x, 2) 

Abfrage

Wie oben gezeigt, ich bin 5 Stichprobe Kombinationen auswählen und unter den Variablen erklärt y'x' .

Um meinen Code zu verbessern, möchte ich dies tun, aber stellen Sie sicher, dass ein Element aus der Liste nicht mehr als einmal in allen Variablenausgaben erscheint, in denen alle Kombinationen verschieden sind und sich nicht wiederholen. Ich möchte dies vorzugsweise erreichen, ohne Elemente aus der Liste entfernen zu müssen, da sie später im Code wiederverwendet werden.

Erwartete Ausgabe (Beispiel):

>>> y1 
['A', 'Q'] 
>>> y2 
['E', 'K'] 
>>> y3 
['C', 'O'] 
>>> y4 
['Z', 'X'] 
>>> y5 
['P', 'L'] 

Antwort

4

Sie können eine Kopie der Liste Shuffle (Sie sagten, Sie es so muss man eine Kopie, weil Shuffle Arbeiten an Ort und Stelle wieder zu verwenden wollte) und dann zwei Elemente für jede Probe nehmen nur:

import random 

x_copy = x[:] # copy 
random.shuffle(x_copy) 
y1 = x[:2] 
y2 = x[2:4] 
y3 = x[4:6] 
y4 = x[6:8] 
y5 = x[8:10] 

oder wenn Sie wollen nicht die yi s hart codieren:

x_copy = x[:] # copy 
random.shuffle(x_copy) 
y = [x_copy[i*2: (i+1)*2] for i in range(5)] 
print(y) 
# [['W', 'Z'], ['A', 'Q'], ['B', 'J'], ['O', 'D'], ['X', 'E']] 
+0

Das ist perfekt! Danke. Ich mache diesen Teil nicht besonders: "[i * 2: (i + 1) * 2]". Verstand klären? ;) – LearningToPython

+0

Meinst du das Listenverstehen oder den 'x_copy [i * 2: (i + 1) * 2]' Teil? – MSeifert

+0

Ja, ein lil 'Bit;/- Der' Teil 'den du genannt hast;) – LearningToPython

-1

Sie können die Probenschleife über erzeugt und die Elemente aus x entfernen:

x = ['A','B','C','D','E','F', 
'G','H','I','J','K','L', 
'M','N','O','P','Q','R', 
'S','T','U','V','W','X', 
'Y','Z'] 

new_x = x[:] 

import random 
final_list = [] 
for i in range(5): 
    the_sample = random.sample(new_x, 2) 
    final_list.append(the_sample) 
    for b in the_sample: 
     new_x.remove(b) 

Output:

[['C', 'R'], ['L', 'V'], ['W', 'Y'], ['D', 'O'], ['J', 'Q']] 
+0

Danke! Obwohl, "Ich würde das am liebsten erreichen, ohne die Elemente aus der Liste entfernen zu müssen, da sie später im Code wiederverwendet werden." – LearningToPython

+0

Warum der Downvote? – Ajax1234

2

Sie numpy.random.choice verwenden können. Sein Zweck ist es mit (replace=True) oder ohne (replace=False) Ersatz von einem Array-ähnlichen Objekt (das funktioniert auch für Ihre Liste) zu wählen:

import numpy as np 
x = ['A','B','C','D','E','F', 
    'G','H','I','J','K','L', 
    'M','N','O','P','Q','R', 
    'S','T','U','V','W','X', 
    'Y','Z'] 
np.random.choice(x, size=(5, 2), replace=False) 

Ergebnis:

array([['Y', 'Q'], 
     ['W', 'R'], 
     ['O', 'H'], 
     ['Z', 'G'], 
     ['L', 'M']], 
     dtype='<U1') 

Dies gibt einen Array von 5 Reihen, die jeweils eine Ihrer Proben Größe umfassen 2.

1

Sie einfach einen ‚Cache‘ der erzeugten Werte aufbauen könnte - so die Elemente der x werden nicht entfernt:

import random 

class SampleCache(): 
    x = ['A','B','C','D','E','F', 
     'G','H','I','J','K','L', 
     'M','N','O','P','Q','R', 
     'S','T','U','V','W','X', 
     'Y','Z'] 

    def __init__(self): 
     self.cache = [] 

    def get(self): 
     _iterations = 0 
     while 1: 
      sample = random.sample(self.x, 2) 
      if not sample in self.cache: 
       self.cache.append(sample) 
       return sample 

      if _iterations > 1000: # just to prevent NOT to run into an infinite loop 
       break 


s = SampleCache() 
for x in range(25): 
    print(s.get()) 
0

Verwenden Sie random.sample, um eine gemischte Kopie der ursprünglichen Liste und einen Generator zu generieren, der nach Bedarf die gemischten Werte liefert.

def random_sample(x, n): 
    shuffled = random.sample(x, k=len(x)) 
    for val in range(0, len(x), n): 
     yield shuffled[val: val+n] 

print([sample for sample in random_sample(x, 2)]) 

Ausgänge;

[['I', 'O'], ['V', 'T'], ['U', 'J'], ['L', 'A'], 
['E', 'G'], ['Q', 'F'], ['M', 'H'], ['B', 'K'], 
['R', 'P'], ['W', 'N'], ['D', 'S'], ['Z', 'Y'], 
['X', 'C']] 

Wenn Sie genau fünf zufällige Werte dieser dann verwenden;

samples = random_sample(x, 2) 
five_samples = [next(samples) for _ in range(5)] 
print(five_samples) 

Wenn sie ein zu einer Zeit wollen verwenden dann,

samples = random_sample(x, 2) 
print(next(samples)) 
... 
print(next(samples)) 
1

random.sample ist die richtige Methode, Sie müssen es nur einmal statt mit zwei Buchstaben von 5 mal 10 Buchstaben nennen:

import random 
import string 


def random_letters(m=5, n=2): 
    letters = random.sample(string.ascii_uppercase, m * n) 
    return [letters[n * i:n * (i + 1)] for i in range(m)] 

print(random_letters()) 
# [['I', 'X'], ['J', 'U'], ['O', 'W'], ['G', 'C'], ['D', 'F']] 
print(random_letters()) 
# [['J', 'X'], ['N', 'P'], ['A', 'C'], ['O', 'Z'], ['B', 'H']] 
print(random_letters()) 
# [['U', 'T'], ['J', 'N'], ['C', 'H'], ['D', 'I'], ['K', 'P']] 
print(random_letters()) 
# [['U', 'G'], ['L', 'V'], ['A', 'R'], ['J', 'F'], ['S', 'C']] 
print(random_letters()) 
# [['Y', 'C'], ['R', 'B'], ['E', 'I'], ['S', 'T'], ['H', 'X']] 
Verwandte Themen