Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Randomly selecting a different pair of items from a list

Code:

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)

Query

As shown above, I'm selecting 5 random sample combinations and declaring them under the variables y'x'.

To improve my code, I would like to do so, but ensure that an item from the list doesn't appear more than once in all variable outputs, in which all combinations are different and non-repetitive. I would preferably like to achieve this without having to remove items from the list as it is reused later in the code.

Expected Output (Example):

>>> y1
['A', 'Q']
>>> y2
['E', 'K']
>>> y3
['C', 'O']
>>> y4
['Z', 'X']
>>> y5
['P', 'L']
like image 805
ThatOneNoob Avatar asked Jul 18 '17 13:07

ThatOneNoob


2 Answers

You could shuffle a copy of the list (you said you wanted to reuse it so one needs to make a copy because shuffle works in-place) and then just take 2 elements for each sample:

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]

or if you don't want to hardcode the yis:

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']]
like image 124
MSeifert Avatar answered Nov 15 '22 04:11

MSeifert


You can use numpy.random.choice. Its purpose is to choose with (replace=True) or without (replace=False) replacement from an array-like object (which also works for your list):

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)

Result:

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

This returns an array of 5 rows, which each include one of your samples of size 2.

like image 36
jotasi Avatar answered Nov 15 '22 05:11

jotasi