So generieren Sie Zufallszahlen mit der spezifischen Länge in Python

105

Nehmen wir an, ich brauche eine dreistellige Nummer, also wäre es ungefähr so:

>>> random(3)
563

or

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

Antworten:

181

So erhalten Sie eine dreistellige Zufallszahl:

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

(Angenommen, Sie haben wirklich drei Ziffern gemeint und nicht "bis zu drei Ziffern".)

So verwenden Sie eine beliebige Anzahl von Ziffern:

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)

Ausgabe:

33
124
5127
RichieHindle
quelle
7
Mit dieser Lösung eliminieren Sie 10 ** (n-1) Zahlen aus Ihrem zufälligen Pool
Nicu Surdu
4
@NicolaeSurdu: Ja, deshalb habe ich gesagt, dass Sie wirklich drei Ziffern gemeint haben und nicht "bis zu drei Ziffern".
RichieHindle
3
037 ist eine dreistellige Zahl, kleiner als 100 :). Das ist es was ich meinte. Aber ja, für eine Nicht-Lotterie-Anwendung ist Ihre Lösung in Ordnung;)
Nicu Surdu
@NicolaeSurdu Wie kann dieses Snipet Ihnen ein Ergebnis von 037 geben ??? Es ist eine Randint von (100 bis 1000), wenn n == 3
Moldau
3
@moldovean Von oben lesen :). Ich meinte, ich wollte diese Nummer und diese Lösung gibt Ihnen keine Nummern bis zu dieser Anzahl von Ziffern, sondern genau diese Anzahl von Ziffern. Es war mein schlechtes, ich habe die Klausel in der Klammer verpasst.
Nicu Surdu
41

Wenn Sie es als Zeichenfolge möchten (z. B. eine 10-stellige Telefonnummer), können Sie Folgendes verwenden:

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

Wenn Sie eine dreistellige Nummer benötigen und 001-099 gültige Nummern sein möchten, sollten Sie dennoch Randrange / Randint verwenden, da dies schneller als Alternativen ist. Fügen Sie einfach die erforderlichen vorhergehenden Nullen hinzu, wenn Sie in eine Zeichenfolge konvertieren.

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)

Wenn Sie die Zufallszahl nicht als int speichern möchten, können Sie dies auch einfach als Oneliner tun:

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

Python 3.6+ nur Oneliner:

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

Beispielausgaben der oben genannten sind:

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

Als Funktion implementiert:

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
quelle
5

Zählt 0 als mögliche erste Ziffer? Wenn ja, dann brauchen Sie random.randint(0,10**n-1). Wenn nicht , random.randint(10**(n-1),10**n-1). Und wenn Null niemals erlaubt ist, müssen Sie Zahlen mit einer Null explizit ablehnen oder n random.randint(1,9)Zahlen zeichnen .

Nebenbei: Es ist interessant, dass randint(a,b)eine nicht-pythonische "Indizierung" verwendet wird, um eine Zufallszahl zu erhalten a <= n <= b. Man hätte erwarten können, dass es so funktioniert rangeund eine Zufallszahl erzeugt a <= n < b. (Beachten Sie das geschlossene obere Intervall.)

randrangeBeachten Sie angesichts der Antworten in den Kommentaren zu , dass diese durch den Reiniger ersetzt werden können random.randrange(0,10**n), random.randrange(10**(n-1),10**n)und random.randrange(1,10).

Andrew Jaffe
quelle
@ Andrew: a <= n <= b mich auch überrascht. Ich lehne es ab, dieses Extra -1in meinen Code einfügen zu müssen. :-)
RichieHindle
1
@ Andrew - komischerweise der Python-Code für randint (es ist in Lib / random.py) eigentlich nur auf randrange(a, b+1)!
Daniel G
4

Sie könnten sich eine kleine Funktion schreiben, um zu tun, was Sie wollen:

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

Grundsätzlich erhalten 10**(digits-1)Sie die kleinste {stellige} -stellige Zahl und 10**digits - 1die größte {stellige} -stellige Zahl (die zufällig die kleinste {Stelle + 1} -stellige Zahl minus 1 ist!). Dann nehmen wir einfach eine zufällige ganze Zahl aus diesem Bereich.

Daniel G.
quelle
0

Die Antwort von RichieHindle hat mir sehr gut gefallen, aber mir hat die Frage als Übung gefallen. Hier ist eine Brute-Force-Implementierung mit 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)
Schimmel
quelle
0

Scheint die sample () -Methode aus der offiziellen Dokumentation nicht für diesen Zweck geeignet zu sein?

import random

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

Ausgabe:

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

Sie können eine Funktion erstellen, die eine Liste von int verwendet, in eine Zeichenfolge umwandelt, um do int zu verketten, und do int erneut umwandelt.

import random

def generate_random_number(length):
    return int(''.join([str(random.randint(0,10)) for _ in range(length)]))
Andre Machado
quelle
Es werden keine Zahlen einer bestimmten Länge generiert :(
Prometheus