Crear lista aleatoria de enteros en Python

Me gustaría crear una lista aleatoria de enteros para propósitos de prueba. La distribución de los números no es importante. Lo único que se cuenta es el tiempo . Sé que generar números aleatorios es una tarea que requiere mucho tiempo, pero debe haber una mejor manera.

Aquí está mi solución actual:

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 es más rápido que v1, pero no está funcionando a una escala tan grande. Da el siguiente error:

ValueError: muestra más grande que la población

¿Existe una solución rápida y eficiente que funcione a esa escala?

Algunos resultados de la respuesta.

De Andrew: 0.000290962934494

gnibbler’s: 0.0058455221653

De KennyTM: 0.00219276118279

NumPy vino, vio, y conquistó.

No está del todo claro lo que quiere, pero usaría 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 

que da en mi máquina:

 0.0233682730198 0.00781716918945 0.000147947072983 

Tenga en cuenta que randint es muy diferente de random.sample (para que funcione en su caso, tuve que cambiar de 1,000 a 10,000 como señaló uno de los comentaristas: si realmente los quiere de 0 a 1,000, puede dividir por 10).

Y si realmente no te importa la distribución que estás obteniendo, es posible que no entiendas bien tu problema, o números aleatorios, con disculpas si eso suena grosero …

Todos los métodos aleatorios terminan llamando random.random() por lo que la mejor manera es llamarlo directamente:

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

Por ejemplo,

  • random.randint llama a random.randrange .
  • random.randrange tiene un montón de gastos generales para verificar el rango antes de devolver istart + istep*int(self.random() * n) .

NumPy es mucho más rápido aún, por supuesto.

Su pregunta sobre el rendimiento es discutible, ambas funciones son muy rápidas. La velocidad de su código estará determinada por lo que haga con los números aleatorios.

Sin embargo, es importante que entiendas la diferencia en el comportamiento de esas dos funciones. Uno hace muestreo aleatorio con reemplazo, el otro hace muestreo aleatorio sin reemplazo.

En primer lugar, debe usar randrange(0,1000) o randint(0,999) , no randint(0,1000) . El límite superior de randint es inclusivo.

Para que sea eficiente, randint es simplemente un envoltorio de randrange que llama al random , por lo que solo debes usar el random . También, use xrange como el argumento para sample , no range .

Usted podría usar

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

para generar 10,000 números en el rango usando la sample 10 veces.

(Por supuesto, esto no vencerá a 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 

Pero como no te importa la distribución de números, ¿por qué no solo usar:

 range(1000)*(10000/1000) 

?