Tilfeldighet er rundt oss. Når du spinner en mynt eller ruller en dør, kan du aldri være sikker på det endelige resultatet. Denne uforutsigbarheten har mange applikasjoner som å bestemme vinnerne av et heldigstrekk eller generere testtilfeller for et eksperiment med tilfeldige verdier produsert basert på en algoritme.
Med denne bruken i tankene har Python gitt oss den tilfeldige modulen. Du kan bruke den i spill for å gyte fiender tilfeldig eller å blande elementene i en liste.
Nesten alle funksjonene i denne modulen avhenger av grunnleggende tilfeldig()
funksjon, som vil generere en tilfeldig float større enn eller lik null og mindre enn en. Python bruker Mersenne Twister til å generere flyter. Det produserer 53-bits presisjon flyter med en periode på 2 ** 19937-1. Det er faktisk den mest brukte generelle pseudo-tilfeldige tallgeneratoren.
Noen ganger vil du at tilfeldig talgeneratoren skal gjengi rekkefølgen av tallene den opprettet første gang. Dette kan oppnås ved å gi samme frøverdien begge ganger til generatoren ved hjelp av frø (s, versjon)
funksjon. Hvis parameteren s er utelatt, vil generatoren bruke dagens systemtid til å generere tallene. Her er et eksempel:
importere tilfeldig random.seed (100) random.random () # returnerer 0.1456692551041303 random.random () # returnerer 0.45492700451402135
Husk at i motsetning til en myntflip genererer modulen pseudo-tilfeldige tall som er helt deterministiske, så det er ikke egnet for kryptografiske formål.
Modulen har to forskjellige funksjoner for generering av tilfeldige heltall. Du kan bruke randrange (a)
å generere et tilfeldig hele tall mindre enn en
.
På samme måte kan du bruke randrange (a, b [, trinn])
å generere et tilfeldig tall fra rekkevidde (a, b, trinn)
. For eksempel bruker random.randrange (0, 100, 3)
vil bare returnere disse tallene mellom 0 og 100, som også kan deles med 3.
Hvis du vet både den nedre og øvre grensen mellom hvilke du vil generere tallene, kan du bruke en enklere og mer intuitiv funksjon kalt randint (a, b)
. Det er ganske enkelt et alias for randrange (a, b + 1)
.
importere tilfeldig random.randrange (100) # returnerer 65 random.randrange (100) # returnerer 98 random.randrange (0, 100, 3) # returnerer 33 random.randrange (0, 100, 3) # returnerer 75 random.randint 1,6) # returnerer 4 random.randint (1,6) # returnerer 6
For å velge et tilfeldig element fra en gitt ikke-tom sekvens, kan du bruke Valget (seq)
funksjon. Med randint ()
, du er begrenset til et utvalg av tall fra et gitt område. De Valget (seq)
funksjonen lar deg velge et nummer fra hvilken som helst rekkefølge du vil ha.
En annen god ting om denne funksjonen er at den ikke er begrenset til bare tall. Det kan velge hvilken som helst type element tilfeldig fra en sekvens. For eksempel kan navnet på vinneren av en heldig tegning blant fem forskjellige personer, gitt som en streng, bestemmes ved å bruke denne funksjonen lett.
Hvis du vil blande en sekvens i stedet for å velge et tilfeldig element fra det, kan du bruke shuffle (seq)
funksjon. Dette vil resultere i en på plass shuffling av sekvensen. For en sekvens med bare 10 (n) elementer, kan det være totalt 3628800 (n!) Forskjellige arrangementer. Med en større sekvens vil antall mulige permutasjoner bli enda høyere - dette innebærer at funksjonen aldri kan generere alle permutasjoner av en stor sekvens.
La oss si at du må velge 50 studenter fra en gruppe på 100 studenter for å gå på tur.
På dette punktet kan du bli fristet til å bruke Valget (seq)
funksjon. Problemet er at du må ringe det omtrent 50 ganger i beste tilfelle hvor det ikke velger den samme studenten igjen.
En bedre løsning er å bruke prøve (seq, k)
funksjon. Det vil returnere en liste over k unike elementer fra den angitte sekvensen. Den opprinnelige sekvensen er uendret. Elementene i den resulterende listen vil være i valg rekkefølge. Hvis k er større enn antall elementer i selve sekvensen, vil en ValueError bli hevet.
importere tilfeldige ids = [1, 8, 10, 12, 15, 17, 25] random.choice (ids) # returnerer 8 random.choice (ids) # returnerer 15 navn = ['Tom', 'Harry', 'Andrew ',' Robert '] random.choice (navn) # returnerer Tom random.choice (navn) # returnerer Robert random.shuffle (navn) navn # returnerer [' Robert ',' Andrew ',' Tom ',' Harry '] random.sample (navn, 2) # returnerer ['Andrew', 'Robert'] random.sample (navn, 2) # returnerer ['Tom', 'Robert'] navn # returnerer ['Robert', 'Andrew' 'Tom', 'Harry']
Som du kan se, shuffle (seq)
endret den opprinnelige listen, men prøve (seq, k)
holdt det intakt.
I denne delen lærer du om funksjoner som kan brukes til å generere tilfeldige tall basert på spesifikke verdier. Parametrene for de fleste av disse funksjonene er oppkalt etter den tilsvarende variabelen i den fordelingens faktiske ligning.
Når du bare vil ha et tall mellom 0 og 1, kan du bruke tilfeldig()
funksjon. Hvis du vil at nummeret skal være i et bestemt område, kan du bruke uniform (a, b)
fungere med en og b som henholdsvis lavere og høyere grenser.
La oss si at du må generere et tilfeldig tall mellom lav og høy slik at den har en høyere sannsynlighet for å ligge i nærheten av et annet nummer modus. Du kan gjøre dette med triangulær (lav, høy, modus)
funksjon. De lav og høy verdiene vil være 0 og 1 som standard. På samme måte, modus verdiverdier til midtpunktet av lav og høy verdi, noe som resulterer i en symmetrisk fordeling.
Det er også mange andre funksjoner for å generere tilfeldige tall basert på forskjellige distribusjoner. Som et eksempel kan du bruke normalvariate (mu, sigma)
å generere et tilfeldig tall basert på en normal fordeling, med mu som gjennomsnittlig og sigma som standardavvik.
importere tilfeldig random.random () # returnerer 0.8053547502449923 random.random () # returnerer 0.05966180559620815 random.uniform (1, 20) # returnerer 11.970525425108205 random.uniform (1, 20) # returnerer 7.731292430291898 random.triangular (1, 100, 80) # returnerer 42.328674062298816 random.triangular (1, 100, 80) # returnerer 73.54693076132074
Som vi nettopp så, er det mulig å generere tilfeldige tall med ensartet fordeling, samt trekantet eller normal fordeling. Selv i et begrenset område som 0 til 100, er det et uendelig antall flyter som kan genereres. Hva om det er et begrenset sett med elementer, og du vil legge til mer vekt på noen bestemte verdier mens du velger et tilfeldig tall? Denne situasjonen er vanlig i lotterisystemer hvor tall med liten belønning er gitt høy vekting.
Hvis det er akseptabelt for søknaden din å ha vekter som er heltallverdier, kan du lage en liste over elementer hvis frekvens avhenger av vekten. Du kan da bruke Valget (seq)
funksjon for å velge et element fra denne vektede listen tilfeldig. Her er et eksempel som viser valget av et premiebeløp tilfeldig.
importere tilfeldig w_prizes = [('$ 1', 300), ('$ 2', 50), ('$ 10', 5), ('$ 100', 1)] prize_list = [pris for premie, vekt i w_prizes for jeg i rekkevidde (vekt)] random.choice (prize_list) # returnerer '$ 1'
I mitt tilfelle tok det ti forsøk på å få en $ 2 premie valgt fra listen. Sjansene for å få en $ 100 premie ville være mye lavere. På samme måte kan du også legge til fordel for andre slike programmer.
Denne modulen kan være nyttig i mange situasjoner som å blande spørsmålene i et oppdrag eller generere tilfeldige brukernavn eller passord for brukerne ved å bruke tilfeldig rekkefølge()
funksjon. Du kan også generere tilfeldige tall jevnt og gi vekt på tall i et bestemt område. I vår neste opplæring vil vi bruke funksjonene fra denne modulen til å generere tilfeldige data for statistisk analyse.
Har du noen interessante applikasjoner av tilfeldige nummergeneratorer i tankene som kan være nyttige for andre lesere? Gi oss beskjed i kommentarene.