Comment générer un nombre aléatoire avec la longueur spécifique en python

105

Disons que j'ai besoin d'un numéro à 3 chiffres, donc ce serait quelque chose comme:

>>> random(3)
563

or

>>> random(5)
26748
>> random(2)
56
Arty
la source

Réponses:

182

Pour obtenir un nombre aléatoire à 3 chiffres:

from random import randint
randint(100, 999)  # randint is inclusive at both ends

(en supposant que vous vouliez vraiment dire trois chiffres, plutôt que "jusqu'à trois chiffres".)

Pour utiliser un nombre arbitraire de chiffres:

from random import randint

def random_with_N_digits(n):
    range_start = 10**(n-1)
    range_end = (10**n)-1
    return randint(range_start, range_end)

print random_with_N_digits(2)
print random_with_N_digits(3)
print random_with_N_digits(4)

Production:

33
124
5127
RichieHindle
la source
7
Avec cette solution, vous éliminerez 10 ** (n-1) nombres de votre pool aléatoire
Nicu Surdu
5
@NicolaeSurdu: Oui, c'est pourquoi j'ai dit en supposant que vous vouliez vraiment dire trois chiffres, plutôt que "jusqu'à trois chiffres".
RichieHindle
3
037 c'est un nombre à 3 chiffres, inférieur à 100 :). C'est ce que je voulais dire. Mais oui, pour une application non-loterie, votre solution est très bien;)
Nicu Surdu
@NicolaeSurdu Comment ce snipet peut-il vous donner un résultat de 037 ??? c'est un randint de (100 à 1000) si n == 3
moldave
3
@moldovean Lire du haut :). Je voulais dire que je voulais ce numéro et cette solution ne vous donnera pas des nombres allant jusqu'à ce nombre de chiffres, mais plutôt exactement ce nombre de chiffres. C'était ma faute, j'ai raté la clause entre parenthèses.
Nicu Surdu
41

Si vous le souhaitez sous forme de chaîne (par exemple, un numéro de téléphone à 10 chiffres), vous pouvez utiliser ceci:

n = 10
''.join(["{}".format(randint(0, 9)) for num in range(0, n)])
Osman
la source
'' .join (str (randint (0, 9)) for _ in range (n))
Mike Fogel
13

Si vous avez besoin d'un nombre à 3 chiffres et que vous voulez que 001-099 soit un nombre valide, vous devez toujours utiliser randrange / randint car il est plus rapide que les alternatives. Ajoutez simplement les zéros précédents nécessaires lors de la conversion en chaîne.

import random
num = random.randrange(1, 10**3)
# using format
num_with_zeros = '{:03}'.format(num)
# using string's zfill
num_with_zeros = str(num).zfill(3)

Alternativement, si vous ne voulez pas enregistrer le nombre aléatoire en tant qu'int, vous pouvez simplement le faire comme un oneliner:

'{:03}'.format(random.randrange(1, 10**3))

python 3.6+ uniquement oneliner:

f'{random.randrange(1, 10**3):03}'

Voici des exemples de résultats de ce qui précède:

  • «026»
  • «255»
  • «512»

Implémenté en fonction:

import random

def n_len_rand(len_, floor=1):
    top = 10**len_
    if floor > top:
        raise ValueError(f"Floor {floor} must be less than requested top {top}")
    return f'{random.randrange(floor, top):0{len_}}'
Brian
la source
5

Le 0 compte-t-il comme premier chiffre possible? Si tel est le cas, vous en avez besoin random.randint(0,10**n-1). Dans le cas contraire, random.randint(10**(n-1),10**n-1). Et si zéro n'est jamais autorisé, vous devrez rejeter explicitement les nombres contenant un zéro ou dessiner des n random.randint(1,9)nombres.

A part: il est intéressant d' randint(a,b)utiliser une "indexation" quelque peu non pythonique pour obtenir un nombre aléatoire a <= n <= b. On aurait pu s'attendre à ce que cela fonctionne comme range, et produise un nombre aléatoire a <= n < b. (Notez l'intervalle supérieur fermé.)

Compte tenu des réponses dans les commentaires sur randrange, notez que ceux-ci peuvent être remplacés par le nettoyant random.randrange(0,10**n), random.randrange(10**(n-1),10**n)et random.randrange(1,10).

Andrew Jaffe
la source
@Andrew: a <= n <= bm'a surpris aussi. Je n'aime pas avoir à mettre ce supplément -1dans mon code. :-)
RichieHindle
1
@Andrew - curieusement, le code Python pour randint(il est dans Lib / random.py) n'appelle en fait que randrange(a, b+1)!
Daniel G
4

Vous pourriez vous écrire une petite fonction pour faire ce que vous voulez:

import random
def randomDigits(digits):
    lower = 10**(digits-1)
    upper = 10**digits - 1
    return random.randint(lower, upper)

Fondamentalement, 10**(digits-1)vous donne le plus petit nombre à {chiffre} -digit, et 10**digits - 1vous donne le plus grand nombre à {digit} -digit (qui se trouve être le plus petit nombre à {chiffre + 1} -digit moins 1!). Ensuite, nous prenons simplement un entier aléatoire dans cette plage.

Daniel G
la source
0

J'ai beaucoup aimé la réponse de RichieHindle, mais j'ai aimé la question en tant qu'exercice. Voici une implémentation de force brute utilisant des chaînes :)

import random
first = random.randint(1,9)
first = str(first)
n = 5

nrs = [str(random.randrange(10)) for i in range(n-1)]
for i in range(len(nrs))    :
    first += str(nrs[i])

print str(first)
moldave
la source
0

D'après la documentation officielle , ne semble-t-il pas que la méthode sample () soit appropriée à cet effet?

import random

def random_digits(n):
    num = range(0, 10)
    lst = random.sample(num, n)
    print str(lst).strip('[]')

Production:

>>>random_digits(5)
2, 5, 1, 0, 4
Kerwei
la source
0

Vous pouvez créer une fonction qui consomme une liste de int, se transforme en chaîne pour concaténer et lancer à nouveau do int, quelque chose comme ceci:

import random

def generate_random_number(length):
    return int(''.join([str(random.randint(0,10)) for _ in range(length)]))
André Machado
la source
il ne génère pas de nombres d'une longueur particulière :(
Prometheus