我如何创build一个唯一的随机数列表?

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

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

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

 random.sample(range(100), 10) 

参考你特定的代码示例,你可能想要从文件中读取所有的行,然后从内存中保存的列表中select随机行。 例如:

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

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

为什么不创build一个1..100的清单,并用Fisher-Yatesalgorithm进行混洗?

Greg Hewgill的作品(+1),但是如果样本量很小,但是人口是巨大的(例如random.sample(insanelyLargeNumber, 10)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 

你可以像这样使用随机模块中的shuffle函数:

 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 

在这里请注意,shuffle方法并不像所期望的那样返回任何列表,它只是对通过引用传递的列表进行混洗。

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

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

更新 :@Greg指出:因为这是Python,使用random.shuffle()

如果您需要抽取非常大的数字,则不能使用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 

这个function解决了这两个问题:

 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 

如果您希望确保添加的号码是唯一的,则可以使用Set对象

如果使用2.7或更高版本,或者如果不是,则导入集合模块。

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

你可以使用Numpy库来快速回答,如下所示 –

给定的代码片段列出了0到5之间的6个唯一数字。 您可以根据您的舒适度调整参数。

 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中所看到的那样引入任何约束。

希望这个对你有帮助。

从win xp的CLI中:

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

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

因为random.randint经常重复一个数字,我使用range(7) ,然后缩短到6的长度。

偶尔如果一个数字重复2次以上,结果列表长度将小于6。

编辑:但是, random.sample(range(6,49),6)是正确的方式去。

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