我如何列出随机唯一元组的列表?

问题描述 投票:0回答:2

我已经查看了与该问题类似的几个答案,而且似乎所有人都提供了很好的oneliner答案,但是,仅解决了通过删除重复项使列表唯一的事实。我需要列表中有5。

我唯一能想到的代码就是这样:

from random import *

tuples = []

while len(tuples) < 5:
    rand = (randint(0, 6), randint(0,6))
    if rand not in tuples:
        tuples.append(rand)

我觉得有一种更简单的方法,但我不知道。我尝试从随机玩sample():

sample((randint(0,6), randint(0,6)), 5)

但是这给了我一个“样本大于总体或为负”错误。

python python-3.x random tuples unique
2个回答
3
投票

一种快速方法是使用itertools.product生成所有元组可能性,然后使用sample从中选择5个:

from itertools import product
from random import sample
sample(list(product(range(7), repeat=2)), k=5)

0
投票

对于这么少的一组输入,只需生成所有可能的输出,然后将它们sample

 import itertools
 import random

 size = 6
 random.sample(list(itertools.product(range(size+1), repeat=2)), 5)

尽管您指出界限(size)可能是一个参数,并且如果界限可能更大,这可能是个问题(您将生成size ** 2tuples以选择[ C0],并且内存使用情况可能会失控)。如果这是一个问题,考虑到您只需要一对整数,则有一个便宜的技巧:选择one随机整数,对两个结果整数进行编码,然后对其进行解码。例如:

5

由于size = 6 raw_sample = random.sample(range((size + 1) ** 2), 5) decoded_sample = [divmod(x, size+1) for x in raw_sample)] 的开销为零(内存使用情况与长度无关),您可以从中精确选择五个值,开销与所选的五个成正比,而不是49个可能的结果。然后,您可以根据单个值的范围(在这种情况下,包括0到range,所以size个可能的值)的范围来计算商和余数,从而便宜地获得高和低结果。

性能差异非常明显;比较:

size + 1

至:

def unique_random_pairs_by_product(size):
    return random.sample(list(itertools.product(range(size+1), repeat=2)), 5)

def unique_random_pairs_optimized(size): val_range = size + 1 return [divmod(x, val_range) for x in random.sample(range(val_range * val_range), 5)] 版本花费的时间甚至比参数optimized少15%(6为〜4.65μs,product为〜3.95μs)。但是在optimizedsize下,您根本看不到比例因子。对于6size=100仅增加到〜4.35μs(时间略有增加,因为较大的optimized更有可能不得不分配新的range,而不是使用较小的int缓存),而int跃升至387μs,相差近100倍。对于productsize=1000的时间跳至63.8 ms,而product保持〜4.35μs;运行时间相差10,000倍(并且内存使用率甚至更高)。如果optimized大于该值,则基于size的解决方案将迅速达到人类甚至注意到一次采样的延迟的程度。 product解决方案将继续以相同的性能运行(optimized的成本具有难以置信的微小差异)。

© www.soinside.com 2019 - 2024. All rights reserved.