2012-03-18 50 views
42

我尝试使用random.randint(0, 100),但有些数字是相同的。有没有一种方法/模块来创建一个列表唯一的随机数字?如何创建独特的随机数列表?

def getScores(): 
    # open files to read and write 
    f1 = open("page.txt", "r"); 
    p1 = open("pgRes.txt", "a"); 

    gScores = []; 
    bScores = []; 
    yScores = []; 

    # run 50 tests of 40 random queries to implement "bootstrapping" method 
    for i in range(50): 
     # get 40 random queries from the 50 
     lines = random.sample(f1.readlines(), 40); 
+7

如果他们是独特的,那么他们并不是真正的随机。 – 2012-03-18 02:38:06

+1

@ IgnacioVazquez-Abrams im试图实施一种方法我的教授称为“bootstrapping”,我们正在搜索引擎上做一些“研究”。 – iCodeLikeImDrunk 2012-03-18 02:47:32

+0

@ IgnacioVazquez-Abrams他们是如果他们代表随机选择而不替换。这是一个关于一般使用的编程语言的问题......我们使用*它的东西 – 2016-02-04 21:34:38

回答

78

这将返回一个从0到99范围内选择的10个数字的列表,没有重复。

random.sample(range(100), 10) 

参照特定的代码示例,你可能想从文件一次读取所有的行,然后选择在内存中保存的列表随机线。例如:

all_lines = f1.readlines() 
for i in range(50): 
    lines = random.sample(all_lines, 40) 

这样,您只需要在循环之前从文件中实际读取一次。这样做要比找回文件的开始更有效率,并且每次循环迭代都要再次调用f1.readlines()

+0

我也试过这个,lines = random.sample(f1.readlines(),40);它不断给我“样本大于人口”,当我试图通过一个for循环运行..任何建议? – iCodeLikeImDrunk 2012-03-18 02:38:51

+1

你的源代码包含少于40行,所以'random.sample()'不能给你一个没有重复的40行的列表。 – 2012-03-18 02:39:49

+0

列表调用是不必要的,我认为(对于2和3)。 – DSM 2012-03-18 02:39:55

3

如果从1到N的N个数字的列表是随机生成的,那么是的,可能会重复某些数字。

如果您需要随机顺序从1到N的数字列表,请使用inegeters 1到N填充数组,然后使用Fisher-Yates shuffle

更新:作为@格雷格指出:由于这是Python的,使用random.shuffle()

7

为什么不创建的1..100列表,并与Fisher-Yates算法洗牌呢?

+15

或者,因为这是Python,所以'random.shuffle()'... – 2012-03-18 02:40:13

+3

有时只是第一个是不够的... :) – 2012-03-18 02:44:59

1

如果你希望确保所添加的编号是唯一的,你可以使用,如果使用2.7或更高版本,Set object

,或者如果不导入套模块。

正如其他人所提到的,这意味着数字并不是真正的随机数。

6

Greg Hewgill的作品(+1),但如果样本量很小,但人口数量巨大(例如random.sample(insanelyLargeNumber, 10)),则记忆可能会出现问题。

为了解决这个问题,我会去这样的:

answer = set() 
sampleSize = 10 
answerSize = 0 

while answerSize < sampleSize: 
    r = random.randint(0,100) 
    if r not in answer: 
     answerSize += 1 
     answer.add(r) 
# answer now contains 10 unique, random integers from 0.. 100 
4

可以使用洗牌函数从random模块是这样的:在这里

import random 

my_list = list(xrange(1,100)) # list of integers from 1 to 99 
           # adjust this boundaries to fit your needs 
random.shuffle(my_list) 
print my_list # <- List of unique random numbers 

注意洗牌方法没有按不会像所期望的那样返回任何列表,它只会拖曳通过引用传递的列表。

0

在Win XP的命令行:

python -c "import random; print(sorted(set([random.randint(6,49) for i in range(7)]))[:6])" 

在加拿大,我们有6/49乐透。我只是将上面的代码包装在lotto.bat中,然后运行C:\home\lotto.batC:\home\lotto

由于random.randint经常重复的数,我使用setrange(7),然后将其缩短的6

长度偶尔如果一个重复数目所得到的列表长度的2倍以上将小于6

编辑:但是,random.sample(range(6,49),6)是正确的路要走。

0

import random result=[] for i in range(1,50): rng=random.randint(1,20) result.append(rng)

2

如果您需要的采样非常大的数字,不能使用range

random.sample(range(10000000000000000000000000000000), 10) 

,因为它抛出:

OverflowError: Python int too large to convert to C ssize_t 

另外,如果random.sample不能产生想要的项目数由于范围太小

random.sample(range(2), 1000) 

它抛出:

ValueError: Sample larger than population 

此功能解决两个问题:

import random 

def random_sample(count, start, stop, step=1): 
    def gen_random(): 
     while True: 
      yield random.randrange(start, stop, step) 

    def gen_n_unique(source, n): 
     seen = set() 
     seenadd = seen.add 
     for i in (i for i in source() if i not in seen and not seenadd(i)): 
      yield i 
      if len(seen) == n: 
       break 

    return [i for i in gen_n_unique(gen_random, 
            min(count, int(abs(stop - start)/abs(step))))] 

中的用法非常大的数字:

print('\n'.join(map(str, random_sample(10, 2, 10000000000000000000000000000000)))) 

样品结果:

7822019936001013053229712669368 
6289033704329783896566642145909 
2473484300603494430244265004275 
5842266362922067540967510912174 
6775107889200427514968714189847 
9674137095837778645652621150351 
9969632214348349234653730196586 
1397846105816635294077965449171 
3911263633583030536971422042360 
9864578596169364050929858013943 

使用其中的范围比要求的项目数量较小:

print(', '.join(map(str, random_sample(100000, 0, 3)))) 

样品结果:

2, 0, 1 

它还可以与负范围和步骤:

print(', '.join(map(str, random_sample(10, 10, -10, -2)))) 
print(', '.join(map(str, random_sample(10, 5, -5, -2)))) 

样品结果:

2, -8, 6, -2, -4, 0, 4, 10, -6, 8 
-3, 1, 5, -1, 3 
1

您可以使用numpy的库进行快速的答案如下 -

由于代码片断清单跌6个独特数字0到5 之间的范围内可以调整参数,为您的舒适。

import numpy as np 
import random 
a = np.linspace(0, 5, 6) 
random.shuffle(a) 
print(a) 

输出

[ 2. 1. 5. 3. 4. 0.] 

它不把任何约束,因为我们在random.sample看到称为here

希望这会有所帮助。