Создать случайный список целых чисел в 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)

?