Come generare un numero casuale con la lunghezza specifica in Python


105

Diciamo che ho bisogno di un numero di 3 cifre, quindi sarebbe qualcosa del tipo:

>>> random(3)
563

or

>>> random(5)
26748
>> random(2)
56

Risposte:


182

Per ottenere un numero casuale di 3 cifre:

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

(supponendo che tu intenda veramente tre cifre, anziché "fino a tre cifre".)

Per utilizzare un numero arbitrario di cifre:

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)

Produzione:

33
124
5127

7
Con questa soluzione, eliminerai 10 ** (n-1) numeri dal tuo pool casuale
Nicu Surdu

5
@NicolaeSurdu: Sì, è per questo che ho detto supponendo che tu intendessi davvero tre cifre, piuttosto che "fino a tre cifre".
RichieHindle

3
037 è un numero di 3 cifre, inferiore a 100 :). Ecco cosa intendevo. Ma sì, per un'applicazione non lotteria, la tua soluzione va benissimo;)
Nicu Surdu

@NicolaeSurdu Come può questo snipet darti un risultato di 037 ??? è un randint da (100 a 1000) se n == 3
moldavo

3
@moldovean Leggi dall'alto :). Volevo dire che volevo quel numero e questa soluzione non ti darà numeri fino a quel numero di cifre ma piuttosto esattamente quel numero di cifre. È stata colpa mia, mi mancava la clausola tra parentesi.
Nicu Surdu

41

Se lo vuoi come una stringa (ad esempio, un numero di telefono di 10 cifre) puoi usare questo:

n = 10
''.join(["{}".format(randint(0, 9)) for num in range(0, n)])

.join (str (randint (0, 9)) for _ in range (n))
Mike Fogel

13

Se hai bisogno di un numero di 3 cifre e vuoi che 001-099 siano numeri validi, dovresti comunque usare randrange / randint in quanto è più veloce delle alternative. Basta aggiungere gli zeri precedenti necessari durante la conversione in una stringa.

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)

In alternativa, se non vuoi salvare il numero casuale come int, puoi farlo semplicemente come oneliner:

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

python 3.6+ solo oneliner:

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

I risultati di esempio di quanto sopra sono:

  • '026'
  • '255'
  • '512'

Implementato come funzione:

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_}}'

5

0 conta come possibile prima cifra? Se è così, allora hai bisogno random.randint(0,10**n-1). In caso contrario random.randint(10**(n-1),10**n-1),. E se lo zero non è mai consentito, dovrai rifiutare esplicitamente i numeri con uno zero o disegnare n random.randint(1,9)numeri.

A parte: è interessante che randint(a,b)utilizzi una "indicizzazione" in qualche modo non pitonica per ottenere un numero casuale a <= n <= b. Ci si sarebbe potuti aspettare che funzionasse come rangee producesse un numero casuale a <= n < b. (Notare l'intervallo superiore chiuso.)

Date le risposte nei commenti circa randrange, nota che questi possono essere sostituiti con il più pulito random.randrange(0,10**n), random.randrange(10**(n-1),10**n)e random.randrange(1,10).


@ Andrew: ha a <= n <= bsorpreso anche me. Mi risento di dover mettere quel extra -1nel mio codice. :-)
RichieHindle

1
@Andrew - abbastanza stranamente, il codice Python per randint(è in Lib / random.py) in realtà chiama solo randrange(a, b+1)!
Daniel G

4

Potresti scrivere una piccola funzione per fare quello che vuoi:

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

Fondamentalmente, 10**(digits-1)ti dà il numero più piccolo di {cifra} cifre, e 10**digits - 1ti dà il numero più grande di {cifra} cifre (che sembra essere il numero più piccolo di {cifra + 1} cifre meno 1!). Quindi prendiamo un numero intero casuale da quell'intervallo.


0

Mi è piaciuta molto la risposta di RichieHindle, tuttavia mi è piaciuta la domanda come esercizio. Ecco un'implementazione della forza bruta usando le stringhe :)

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)

0

Dalla documentazione ufficiale , non sembra che il metodo sample () sia appropriato a questo scopo?

import random

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

Produzione:

>>>random_digits(5)
2, 5, 1, 0, 4

0

Potresti creare una funzione che consuma un elenco di int, si trasforma in stringa per concatenare e lanciare di nuovo int, qualcosa del genere:

import random

def generate_random_number(length):
    return int(''.join([str(random.randint(0,10)) for _ in range(length)]))

non genera numeri di una lunghezza particolare :(
Prometheus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.