Jak wygenerować liczbę losową o określonej długości w Pythonie

105

Powiedzmy, że potrzebuję 3-cyfrowego numeru, więc wyglądałoby to tak:

>>> random(3)
563

or

>>> random(5)
26748
>> random(2)
56
Pretensjonalny
źródło

Odpowiedzi:

186

Aby otrzymać losową 3-cyfrową liczbę:

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

(zakładając, że naprawdę chodziło Ci o trzy cyfry, a nie o „maksymalnie trzy cyfry”).

Aby użyć dowolnej liczby cyfr:

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)

Wynik:

33
124
5127
RichieHindle
źródło
7
Dzięki temu rozwiązaniu wyeliminujesz 10 ** (n-1) liczb z puli losowej
Nicu Surdu,
5
@NicolaeSurdu: Tak, właśnie dlatego powiedziałem, zakładając, że naprawdę masz na myśli trzy cyfry, a nie „maksymalnie trzy cyfry”.
RichieHindle
3
037 to 3-cyfrowy numer mniejszy niż 100 :). O to mi chodziło. Ale tak, w przypadku aplikacji innej niż loteria twoje rozwiązanie jest w porządku;)
Nicu Surdu,
@NicolaeSurdu W jaki sposób ten snipet może dać wynik 037 ??? jest to randint od (100 do 1000), jeśli n == 3
mołdawski
3
@moldovean Czytaj od góry :). Chodziło mi o to, że chciałem mieć ten numer, a to rozwiązanie nie da ci liczb do tej liczby cyfr, ale raczej dokładnie taką liczbę cyfr. To był mój błąd, brakowało mi klauzuli w nawiasie.
Nicu Surdu,
41

Jeśli chcesz, aby był to ciąg (na przykład 10-cyfrowy numer telefonu), możesz użyć tego:

n = 10
''.join(["{}".format(randint(0, 9)) for num in range(0, n)])
osman
źródło
'' .join (str (randint (0, 9)) for _ in range (n))
Mike Fogel
13

Jeśli potrzebujesz 3-cyfrowego numeru i chcesz, aby 001-099 były poprawnymi liczbami, nadal powinieneś używać randrange / randint, ponieważ jest szybszy niż alternatywy. Po prostu dodaj niezbędne poprzedzające zera podczas konwersji na ciąg.

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)

Alternatywnie, jeśli nie chcesz zapisywać losowej liczby jako int, możesz to zrobić po prostu jako oneliner:

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

python 3.6+ tylko oneliner:

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

Przykładowe wyniki powyższego to:

  • „026”
  • „255”
  • „512”

Zaimplementowane jako funkcja:

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
źródło
5

Czy 0 liczy się jako możliwa pierwsza cyfra? Jeśli tak, to potrzebujesz random.randint(0,10**n-1). Jeśli nie random.randint(10**(n-1),10**n-1),. A jeśli zero nigdy nie jest dozwolone, będziesz musiał jawnie odrzucić liczby zawierające zero lub wylosować n random.randint(1,9)liczby.

Na marginesie: interesujące jest to, że randint(a,b)używa nieco nie-pythonowego „indeksowania” do uzyskania liczby losowej a <= n <= b. Można by się spodziewać, że będzie działać podobnie rangei wygeneruje liczbę losową a <= n < b. (Zwróć uwagę na zamknięty górny przedział).

Biorąc pod uwagę odpowiedzi w komentarzach około randrangepamiętać, że mogą one zostać zastąpione przez czystsze random.randrange(0,10**n), random.randrange(10**(n-1),10**n)i random.randrange(1,10).

Andrew Jaffe
źródło
@ Andrew: a <= n <= bteż mnie zaskoczył. Żałuję, że muszę umieszczać ten dodatek -1w moim kodzie. :-)
RichieHindle
1
@Andrew - co zabawne, kod Pythona dla randint(jest w Lib / random.py) w rzeczywistości po prostu wywołuje randrange(a, b+1)!
Daniel G,
4

Możesz napisać sobie małą funkcję, która zrobi, co chcesz:

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

Zasadniczo, 10**(digits-1)daje ci najmniejszą {cyfrę} -cyfrową liczbę i 10**digits - 1największą {cyfrę} -cyfrową liczbę (która jest najmniejszą {cyfra + 1} -cyfrową liczbą minus 1!). Następnie bierzemy losową liczbę całkowitą z tego zakresu.

Daniel G.
źródło
0

Bardzo podobała mi się odpowiedź RichieHindle, jednak spodobało mi się to pytanie jako ćwiczenie. Oto implementacja brutalnej siły przy użyciu ciągów znaków :)

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)
mołdawski
źródło
0

Czy z oficjalnej dokumentacji nie wynika, że ​​metoda sample () jest odpowiednia do tego celu?

import random

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

Wynik:

>>>random_digits(5)
2, 5, 1, 0, 4
kerwei
źródło
0

Możesz stworzyć funkcję, która konsumuje listę int, przekształca w string w celu konkatenacji i rzutowania do int, coś takiego:

import random

def generate_random_number(length):
    return int(''.join([str(random.randint(0,10)) for _ in range(length)]))
Andre Machado
źródło
nie generuje liczb o określonej długości :(
Prometheus