Créer une liste aléatoire d’entiers dans Python

J’aimerais créer une liste aléatoire d’entiers à des fins de test. La dissortingbution des numéros n’est pas importante. La seule chose qui compte est le temps . Je sais que générer des nombres aléatoires est une tâche chronophage, mais il doit y avoir une meilleure solution.

Voici ma solution actuelle:

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 est plus rapide que v1, mais ne fonctionne pas à grande échelle. Il donne l’erreur suivante:

ValueError: échantillon plus grand que la population

Existe-t-il une solution rapide et efficace qui fonctionne à cette échelle?

Quelques résultats de la réponse

Andrew’s: 0.000290962934494

gnibbler: 0.0058455221653

KennyTM’s: 0.00219276118279

NumPy est venu, a vu et a conquis.

Ce que vous voulez n’est pas tout à fait clair, mais j’utiliserais 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 

qui donne sur ma machine:

 0.0233682730198 0.00781716918945 0.000147947072983 

Notez que randint est très différent de random.sample (pour que cela fonctionne dans votre cas, je devais changer le 1000 à 10 000 comme l’a souligné l’un des commentateurs – si vous le voulez vraiment de 0 à 1 000, vous pouvez diviser par dix).

Et si vous ne vous souciez vraiment pas de la dissortingbution que vous obtenez, il est possible que vous ne compreniez pas très bien votre problème, ou que vous ayez des chiffres aléatoires – avec des excuses si cela semble impoli …

Toutes les méthodes aléatoires finissent par appeler random.random() , le meilleur moyen est donc de l’appeler directement:

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

Par exemple,

  • random.randint appelle random.randrange .
  • random.randrange a un tas de surcharge pour vérifier la plage avant de renvoyer istart + istep*int(self.random() * n) .

NumPy est bien plus rapide encore.

Votre question sur les performances est théorique: les deux fonctions sont très rapides. La vitesse de votre code sera déterminée par ce que vous faites avec les nombres aléatoires.

Cependant, il est important de comprendre la différence de comportement entre ces deux fonctions. L’un effectue un échantillonnage aléatoire avec remplacement, l’autre effectue un échantillonnage aléatoire sans remplacement.

Tout d’abord, vous devez utiliser randrange(0,1000) ou randint(0,999) , pas randint(0,1000) . La limite supérieure de randint est inclusive.

Pour efficacement, randint est simplement un wrapper de randrange qui appelle random , vous devez donc utiliser random . En outre, utilisez xrange comme argument pour sample , et non pour xrange la range .

Vous pourriez utiliser

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

pour générer 10 000 numéros dans la gamme en utilisant 10 fois l’ sample .

(Bien sûr, cela ne battra pas 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 

Mais comme vous ne vous souciez pas de la dissortingbution des nombres, pourquoi ne pas utiliser simplement:

 range(1000)*(10000/1000) 

?