2017-07-18 93 views
4

代码:随机从列表中选择一个不同的对项

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) 

查询

如上所示,我选择5个随机样本的组合和变量下声明它们y'x'

为了改进我的代码,我想这样做,但要确保列表中的项目在所有变量输出中都不会出现一次以上,其中所有组合都是不同的且不重复的。我希望能够实现这一点,而不必从列表中删除项目,因为它稍后在代码中重用。

期望输出(实施例):

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

回答

4

你可以随机播放列表的副本(你说你想重用这么一个需要做出一个副本,因为就地洗牌作品),然后只需要2元每个样品:

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] 

,或者你不想硬编码yi S:

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

这很完美!谢谢。我不特别这个部分:'[我* 2:(i + 1)* 2]'。介意澄清? ;) – LearningToPython

+0

你的意思是列表理解还是'x_copy [i * 2:(i + 1)* 2]'部分? – MSeifert

+0

是的,一点点;/- 你提到的'部分'; – LearningToPython

-1

你也可以遍历中产生的采样和移除x的元素:

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) 

输出:

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

谢谢!虽然'我希望能够实现这一点,而不必从列表中删除项目,因为它稍后会在代码中重用。' – LearningToPython

+0

为什么downvote? – Ajax1234

2

您可以使用numpy.random.choice。其目的是(replace=True)选择或不(replace=False)从阵列状物体替代(也适用于您的列表):

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) 

结果:

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

这将返回数组5行,其中每个包括您大小的样品之一2.

1

你可以简单地建立一个生成的值的“缓存” - 这样的x的元素是不能删除:

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

使用random.sample来生成初始列表的混洗副本以及根据需要产生混洗值的生成器。

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

输出;

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

如果你想正好五个随机值,然后利用这一点;

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

如果想让他们一次一个,然后使用,

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

random.sample是正确的方法,你只需要使用2个字母调用一次为10个字母,而不是5次:

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']] 
相关问题