Создать случайный список целых чисел в Python
Я хотел бы создать случайный список целых чисел для целей тестирования. Распределение чисел не важно. Единственное, что считается: время. Я знаю, что генерация случайных чисел - трудоемкая задача, но должен быть лучший способ.
Здесь мое текущее решение:
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
gnibbler's: 0.0058455221653
KennyTM's: 0.00219276118279
NumPy пришел, увидел, завоевал
Спасибо!
Ответы
Ответ 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(для того, чтобы он работал в вашем случае, мне пришлось изменить 1000 на 10000, как заметил один из комментаторов, - если вы действительно хотите, чтобы они находились от 0 до 1000, вы может делить на 10). И если вам действительно все равно, какое распространение вы получаете, то возможно, что вы либо не понимаете свою проблему очень хорошо, либо случайные числа - извинения, если это звучит грубо...
Ответ 2
Все случайные методы в конечном итоге вызывают random.random()
, поэтому лучший способ - называть его напрямую
[int(1000*random.random()) for i in xrange(10000)]
например.
random.randint
calls random.randrange
random.randrange
имеет кучу накладных расходов для проверки диапазона перед возвратом istart + istep*int(self.random() * n)
Изменить: numpy намного быстрее, конечно
Ответ 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)]
для генерации 10 000 номеров в диапазоне с использованием sample
10 раз.
(Конечно, это не будет бить 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)
?