Como gerar um número aleatório com o comprimento específico em python


105

Digamos que eu precise de um número de 3 dígitos, então seria algo como:

>>> random(3)
563

or

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

Respostas:


182

Para obter um número aleatório de 3 dígitos:

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

(presumindo que você realmente quis dizer três dígitos, em vez de "até três dígitos".)

Para usar um número arbitrário de dígitos:

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)

Resultado:

33
124
5127

7
Com esta solução, você eliminará 10 ** (n-1) números de seu conjunto aleatório
Nicu Surdu

5
@NicolaeSurdu: Sim, é por isso que eu disse assumindo que você realmente quis dizer três dígitos, em vez de "até três dígitos".
RichieHindle

3
037 é um número de 3 dígitos, menor que 100 :). Foi isso que eu quis dizer. Mas sim, para um aplicativo que não seja de loteria, sua solução é ótima;)
Nicu Surdu

@NicolaeSurdu Como esse snipet pode dar um resultado de 037 ??? é um randint de (100 a 1000) se n == 3
moldavo

3
@moldovean Leia do início :). Eu quis dizer que eu queria esse número e esta solução não vai te dar números até esse número de dígitos, mas sim exatamente esse número de dígitos. Foi mal minha, perdi a cláusula entre parênteses.
Nicu Surdu

41

Se você quiser como uma string (por exemplo, um número de telefone de 10 dígitos), pode usar isto:

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

'' .join (str (randint (0, 9)) para _ no intervalo (n))
Mike Fogel

13

Se você precisa de um número de 3 dígitos e deseja que 001-099 sejam números válidos, você ainda deve usar randrange / randint, pois é mais rápido do que as alternativas. Basta adicionar os zeros precedentes necessários ao converter em uma string.

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)

Alternativamente, se você não quiser salvar o número aleatório como um inteiro, você pode apenas fazer isso como um oneliner:

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

python 3.6+ somente oneliner:

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

Os exemplos de resultados acima são:

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

Implementado como uma função:

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 como um possível primeiro dígito? Se sim, então você precisa random.randint(0,10**n-1). Se não random.randint(10**(n-1),10**n-1),. E se zero nunca for permitido, você terá que rejeitar explicitamente os números com um zero ou desenhar n random.randint(1,9)números.

À parte: é interessante que randint(a,b)use uma "indexação" um tanto não pythônica para obter um número aleatório a <= n <= b. Seria de se esperar que funcionasse rangee produzisse um número aleatório a <= n < b. (Observe o intervalo superior fechado.)

Dadas as respostas nos comentários sobre randrange, nota que estes podem ser substituídos com o aspirador random.randrange(0,10**n), random.randrange(10**(n-1),10**n)e random.randrange(1,10).


@Andrew: a <= n <= btambém me surpreendeu. Eu me ressinto por ter que colocar aquele extra -1no meu código. :-)
RichieHindle de

1
@Andrew - curiosamente, o código Python para randint(está em Lib / random.py) na verdade apenas chama randrange(a, b+1)!
Daniel G de

4

Você pode escrever uma pequena função para fazer o que quiser:

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

Basicamente, 10**(digits-1)dá-lhe o menor número de {dígito} -digito e 10**digits - 1dá-lhe o maior número de {dígito} -digito (que passa a ser o menor número de {dígito + 1} -digito menos 1!). Então, pegamos um inteiro aleatório desse intervalo.


0

Gostei muito da resposta de RichieHindle, porém gostei da pergunta como um exercício. Aqui está uma implementação de força bruta usando strings :)

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

A partir da documentação oficial , isso não parece que o método () da amostra é apropriada para este fim?

import random

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

Resultado:

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

0

Você poderia criar uma função que consome uma lista de int, se transforma em string para concatenar e lançar do int novamente, algo assim:

import random

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

não está gerando números de um comprimento específico :(
Prometheus,
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.