来自列表的互斥随机抽样

问题描述 投票:2回答:3
input = ['beleriand','mordor','hithlum','eol','morgoth','melian','thingol']

我在不重复任何元素的情况下创建X个大小为Y的列表有麻烦。

我一直在使用:

x = 3
y = 2

import random

output = random.sample(input, y)
# ['mordor', 'thingol']

但是如果我重复一次,那么我会重复。

我希望输出类似

[['mordor', 'thingol'], ['melian', 'hithlum'], ['beleriand', 'eol']]

因为我选择了大小为x = 3(每个列表2个元素)的y = 2(3个列表)。

def random_generator(x,y):
    ....
python random sample mutual-exclusion
3个回答
1
投票

而不是从列表中随机获取两件事,只需随机化列表并对其进行遍历,以创建您指定尺寸的新数组!

import random
my_input = ['beleriand','mordor','hithlum','eol','morgoth','melian','thingol']
def random_generator(array,x,y):
    random.shuffle(array)
    result = []
    count = 0
    while count < x:
        section = []
        y1 = y * count
        y2 = y * (count + 1)
        for i in range (y1,y2):
            section.append(array[i])
        result.append(section)
        count += 1
    return result
print random_generator(my_input,3,2)

2
投票

您可以简单地对原始列表进行混洗,然后从中依次生成n个由m个元素组成的组。可能有少于或多于该数目的组。请注意,input是Python内置函数的名称,因此我将其重命名为words

import itertools
from pprint import pprint
import random

def random_generator(seq, n, m):
    rand_seq = seq[:]  # make a copy to avoid changing input argument
    random.shuffle(rand_seq)
    lists = []
    limit = n-1
    for i,group in enumerate(itertools.izip(*([iter(rand_seq)]*m))):
        lists.append(group)
        if i == limit: break  # have enough
    return lists

words = ['beleriand', 'mordor', 'hithlum', 'eol', 'morgoth', 'melian', 'thingol']
pprint(random_generator(words, 3, 2))

输出:

[('mordor', 'hithlum'), ('thingol', 'melian'), ('morgoth', 'beleriand')]

迭代生成组会更加Pythonic。通过使每个组yield成为一个组,可以轻松地将上述函数转换为生成器,而不是将它们全部返回到相对较长的列表中:

yield

1
投票

您可以将def random_generator_iterator(seq, n, m): rand_seq = seq[:] random.shuffle(rand_seq) limit = n-1 for i,group in enumerate(itertools.izip(*([iter(rand_seq)]*m))): yield group if i == limit: break pprint([group for group in random_generator_iterator(words, 3, 2)]) random.sample配方结合使用。

random.sample

一次运行,结果为:

itertools.grouper

以及下一次运行:

input = ['beleriand','mordor','hithlum','eol','morgoth','melian','thingol']
import itertools
import random
def grouper(iterable,group_size):
    return itertools.izip(*([iter(iterable)]*group_size))

def random_generator(x,y):
    k = x*y
    sample = random.sample(input,k)
    return list(grouper(sample,y))

print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)
© www.soinside.com 2019 - 2024. All rights reserved.