在Python中创建随机的整数列表

时间:2010-11-13 10:52:21

标签: python list random performance

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

这是我目前的解决方案:

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:样本大于人口

是否有一种快速,有效的解决方案能够以这种规模发挥作用?

答案的一些结果

Andrew's:0.000290962934494

gnibbler's:0.0058455221653

KennyTM:0.00219276118279

NumPy来了,看到并征服了。

4 个答案:

答案 0 :(得分:60)

目前还不完全清楚你想要什么,但我会使用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 :(得分:30)

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

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

例如,

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

NumPy当然要快得多。

答案 2 :(得分:5)

关于性能的问题没有实际意义 - 两种功能都非常快。代码的速度将取决于您使用随机数的内容。

但是,了解这两个函数的行为的区别非常重要。一个是随机抽样替换,另一个是随机抽样,没有替换。

答案 3 :(得分:2)

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

为了有效率,randint只是调用randrange的{​​{1}}的包装,因此您应该只使用random。另外,使用random作为xrange的参数,而不是sample

您可以使用

range

使用[a for a in sample(xrange(1000),1000) for _ in range(10000/1000)] 10次在范围内生成10,000个数字。

(当然这不会打败NumPy。)

sample

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

$ 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