在 Python 中创建随机整数列表

Posted

技术标签:

【中文标题】在 Python 中创建随机整数列表【英文标题】:Create random list of integers in Python 【发布时间】:2011-05-09 11:57:56 【问题描述】:

出于测试目的,我想创建一个随机整数列表。数字的分布并不重要。唯一重要的是时间。我知道生成随机数是一项耗时的任务,但一定有更好的方法。

这是我目前的解决方案:

import random
import timeit

# Random lists from [0-999] interval
print [random.randint(0, 1000) for r in xrange(10)] # v1
print [random.choice([i for i in xrange(1000)]) for r in xrange(10)] # v2

# Measurement:
t1 = timeit.Timer('[random.randint(0, 1000) for r in xrange(10000)]', 'import random') # v1
t2 = timeit.Timer('random.sample(range(1000), 10000)', 'import random') # v2

print t1.timeit(1000)/1000
print t2.timeit(1000)/1000

v2 比 v1 更快,但它并没有在如此大的范围内工作。它给出了以下错误:

ValueError:样本大于总体

是否有适用于这种规模的快速、高效的解决方案?

答案的一些结果

安德鲁的:0.000290962934494

咬人的:0.0058455221653

KennyTM 的:0.00219276118279

NumPy 出现、看到并征服了。

【问题讨论】:

当然不行。 random.sample() 耗尽人口,使数字越来越随机。一旦整个种群被耗尽,就不可能进一步抽样。 你说是测试用的,测试需要多长时间? 对于需要时间(但不需要加密和安全性)的模拟,通常使用Linear Congruential Generator (LCG)。我相信Mersenne Twister 很快(但比 LCG 慢),如果我没记错的话,它提供了均匀分布。 【参考方案1】:

不完全清楚你想要什么,但我会使用numpy.random.randint:

import numpy.random as nprnd
import timeit

t1 = timeit.Timer('[random.randint(0, 1000) for r in xrange(10000)]', 'import random') # v1

### Change v2 so that it picks numbers in (0, 10000) and thus runs...
t2 = timeit.Timer('random.sample(range(10000), 10000)', 'import random') # v2
t3 = timeit.Timer('nprnd.randint(1000, size=10000)', 'import numpy.random as nprnd') # v3

print t1.timeit(1000)/1000
print t2.timeit(1000)/1000
print t3.timeit(1000)/1000

在我的机器上给出:

0.0233682730198
0.00781716918945
0.000147947072983

请注意,randint 非常与 random.sample 不同(为了让它在您的情况下工作,我必须将 1,000 更改为 10,000,正如其中一位评论员指出的那样 - 如果您真的想要它们从 0 到 1,000,你可以除以 10)。

如果你真的不在乎你得到什么分布,那么你可能不是很了解你的问题,或者是随机数——如果这听起来很粗鲁,请道歉......

【讨论】:

+1 for numpy,如果 Stiggo 需要这么多随机数,可能值得为此安装 numpy 安德鲁,你对分发的看法是完全正确的。但这不是真的。只是朋友之间的挑战。 :D 干杯!【参考方案2】:

所有随机方法最终都会调用random.random(),所以最好的方法是直接调用它:

[int(1000*random.random()) for i in xrange(10000)]

例如,

random.randint 致电random.randrangerandom.randrange 在返回 istart + istep*int(self.random() * n) 之前检查范围有很多开销。

NumPy 当然还是要快得多。

【讨论】:

+1 我刚才只是在挖掘这一切,最终认为randrange 最终导致了对getrandbits 的调用。我错过了您必须实例化 SystemRandom 才能成为行为。谢谢你让我看得更仔细。 @Stiggo,当然,我认为不使用 numpy 的唯一原因是您的平台不支持 numpy。例如。谷歌应用引擎 在 Python3 中,random.randrange(1000) 旨在产生比 random.random()*1000 更均匀的分布。请参阅此处的第 9.6.2 节:docs.python.org/3/library/random.html @AlexeyPolonsky,不错的接机。如果我们很乐意将数字取到 1023,那么 [getrandbits(10) for r in range(10000)] 比我的答案中的列表理解快 9 倍 @JohnLaRooy 谢谢!这实际上更有用!【参考方案3】:

您关于性能的问题没有实际意义——这两个功能都非常快。您的代码速度将取决于您对随机数做什么

但是,重要的是您要了解这两个函数的行为差异。一种是有放回随机抽样,另一种是无放回随机抽样。

【讨论】:

【参考方案4】:

首先,您应该使用randrange(0,1000)randint(0,999),而不是randint(0,1000)randint 的上限包括在内。

为了高效,randint 只是 randrange 的包装器,它调用 random,所以你应该只使用 random。另外,使用xrange 作为sample 的参数,而不是range

你可以使用

[a for a in sample(xrange(1000),1000) for _ in range(10000/1000)]

使用sample 10 次生成范围内的 10,000 个数字。

(当然这不会击败 NumPy。)

$ python2.7 -m timeit -s 'from random import randrange' '[randrange(1000) for _ in xrange(10000)]'
10 loops, best of 3: 26.1 msec per loop

$ python2.7 -m timeit -s 'from random import sample' '[a%1000 for a in sample(xrange(10000),10000)]'
100 loops, best of 3: 18.4 msec per loop

$ python2.7 -m timeit -s 'from random import random' '[int(1000*random()) for _ in xrange(10000)]' 
100 loops, best of 3: 9.24 msec per loop

$ python2.7 -m timeit -s 'from random import sample' '[a for a in sample(xrange(1000),1000) for _ in range(10000/1000)]'
100 loops, best of 3: 3.79 msec per loop

$ python2.7 -m timeit -s 'from random import shuffle
> def samplefull(x):
>   a = range(x)
>   shuffle(a)
>   return a' '[a for a in samplefull(1000) for _ in xrange(10000/1000)]'
100 loops, best of 3: 3.16 msec per loop

$ python2.7 -m timeit -s 'from numpy.random import randint' 'randint(1000, size=10000)'
1000 loops, best of 3: 363 usec per loop

但既然你不关心数字的分布,为什么不直接使用:

range(1000)*(10000/1000)

?

【讨论】:

randrange(1000) 在我的电脑上花费的时间是1000*int(random()) 的两倍以上 10000/1000的目的是什么?

以上是关于在 Python 中创建随机整数列表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 python 中创建一个函数,它将整数列表作为输入并输出只有两个值的较小列表?

在 Torch 中,如何从整数标签列表中创建 1-hot 张量?

如何在python中创建字节列表?

如何在python中创建二维列表

如何在 Python 中创建嵌套列表

在python中创建堆栈列表