Python 標準庫:random

Python 中的 random 模塊用于生成各種分布的隨機數(shù)。random 模塊可以生成隨機浮點數(shù)、整數(shù)、字符串,甚至幫助你隨機選擇列表序列中的一個元素,打亂一組數(shù)據(jù)等。

在 Python 中,實現(xiàn)我們比較熟悉的均勻分布、正態(tài)(高斯)分布都非常方便,此外,還有對數(shù)正態(tài)、負指數(shù)、伽馬和 β 分布的函數(shù)。

幾乎所有模塊函數(shù)都依賴于基本函數(shù)random(),在 [0.0,1.0) 中均勻地生成隨機浮點。Python 使用 Mersenne Twister 作為核心生成器。它產(chǎn)生 53 位精確度浮點數(shù),周期為2 ** 19937-1。底層使用 C 實現(xiàn)既快又線程安全。Mersenne Twister 是現(xiàn)存最廣泛測試的隨機數(shù)生成器之一。然而,它不適合于所有目的,比如不適合于加密用途。

警告:該模塊的偽隨機生成器不應該用于安全目的。

1. random.random

函數(shù)是這個模塊中最常用的方法了,它會生成一個隨機的浮點數(shù),范圍是在 0.0~1.0 之間。

2. random.uniform

它可以設定浮點數(shù)的范圍,一個是上限,一個是下限。random.uniform 的函數(shù)原型為:random.uniform(a, b),用于生成一個指定范圍內(nèi)的隨機符點數(shù),兩個參數(shù)其中一個較大的數(shù)是上限,較小的數(shù)是下限。

>>> import random
>>> print(random.uniform(10, 20))
12.2990031101
>>> print(random.uniform(20,10))
13.597102709

3. random.sample

可以從指定的序列中,隨機地選擇元素得到指定長度的列表,不修改原先的序列。random.sample 的函數(shù)原型為:random.sample(sequence, k),其中的兩個參數(shù)一個為序列,另一個為新序列的長度。

import random

orig_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
slice_list = random.sample(orig_list, 5)
print(orig_list)
print(slice_list)

輸出:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[4, 3, 2, 8, 6]

4. random.choice

random.choice 從序列中獲取一個隨機元素。其函數(shù)原型為:random.choice(sequence)。參數(shù) sequence 表示一個有序類型, 它在 python 中不是一種特定的類型,而是泛指一系列的類型。列表、元組、字符串都屬于 sequence。下面是使用 choice 的一些例子:

>>> print(random.choice("學習Python"))
學
>>> print(random.choice(["oatmeal","is","a","cute","man"]))
is
>>> print(random.choice(("Tuple","List","Dict")))
Tuple
>>> 

然后我們再來個實際點的例子,比如你要幫領(lǐng)導寫個發(fā)言稿, 你先收集好領(lǐng)導平時經(jīng)常用的詞或者語句, 用 random.choice 從這些語句中隨機的選擇拼接,這樣就不用費腦筋就可以完成一篇文章了, 當然寫出來后還得通順通順。

import random
import textwrap

OPENING_WORDS = ['Our', 'clear', 'strategic', 'direction', 'is', 'to', 'invoke',]

PHRASE_TABLE = (
    ("accountable",         "transition",           "leadership"),
    ("driving",             "strategy",             "implementation"),
    ("drilling down into",  "active",               "core business objectives"),
    ("next billion",        "execution",            "with our friends in <other corp.>"),
    ("creating",            "next-generation",      "franchise platform"),
    ("<big corp.>'s",       "volume and",           "value leadership"),
    ("significant",         "end-user",             "experience"),
    ("transition",          "from <small corp.>",   "to <other corp.>'s platform"),
    ("integrating",         "shared",               "services"),
    ("empowered to",        "improve and expand",   "our portfolio of experience"),
    ("deliver",             "new",                  "innovation"),
    ("ramping up",          "diverse",              "collaboration"),
    ("next generation",     "mobile",               "ecosystem"),
    ("focus on",            "growth and",           "consumer delight"),
    ("management",          "planning",             "interlocks"),
    ("necessary",           "operative",            "capabilities"),
    ("knowledge",           "optimization",         "initiatives"),
    ("modular",             "integration",          "environment"),
    ("software",            "creation",             "processes"),
    ("agile",               "working",              "practices"),
)

INSERTS = ('for', 'with', 'and', 'as well as', 'by',
           'whilst not forgetting',
           '. Of course',
           '. To be absolutely clear',
           '. We need',
           'and unrelenting',
           'with unstoppable',
)

def get_phrase():
    """Return a phrase by choosing words at random from each column of the PHRASE_TABLE."""
    return [random.choice(PHRASE_TABLE)[i] for i in range(3)]

def get_insert():
    """Return a randomly chosen set of words to insert between phrases."""
    return random.choice(INSERTS)

def write_speech(n):
    """Write a speech with the opening words followed by n random phrases
    interspersed with random inserts."""
    phrases = OPENING_WORDS
    for i in range(n):
        phrases.extend(get_phrase())
        if i != n-1:
            phrases.append(get_insert())

    text = ' '.join(phrases) + '.'
    print(textwrap.fill(text))

if __name__ == '__main__':
    write_speech(8)

開始這篇文章可以有個固定的開頭,把這些詞存在 OPENING_WORDS 列表里。常用的語句放在 PHRASE_TABLE 元組里, 把它寫成三列的形式, 每次從這三列里各選一個詞組成一個新的語句。 然后還得從 INSERTS 里面選一個連接詞。

在從 PHRASE_TABLE 選擇詞匯的時候使用了 [random.choice(PHRASE_TABLE)[i] for i in range(3)] 語句, 注意random.choice在這一句被執(zhí)行了三次,每一次隨機的選擇表里面的某一行的元組,然后把元組中對應列的詞匯找出來。

輸出:

Our clear strategic direction is to invoke next generation planning
collaboration and unrelenting next billion shared experience for
accountable mobile innovation for driving shared with our friends in
<other corp.> with unstoppable focus on mobile initiatives . Of course
significant execution capabilities and unrelenting ramping up
integration innovation and unrelenting focus on execution ecosystem.

5. random.randrange

random.randrange(stop)
random.randrange(start, stop[, step])
從 range(start, stop, step) 返回一個 start 到 end 范圍內(nèi)的隨機整數(shù)(start,end,step 都是整數(shù),不包含 end),可以指定 step。
下面我們利用 randrange 實現(xiàn)一個 21 點撲克牌游戲。

import random
 
def ask_user(prompt, response1, response2):
    """
    Ask user for a response in two responses.
    prompt (str) - The prompt to print to the user
    response1 (str) - One possible response that the user can give
    response2 (str) - Another possible response that the user can give
    """
     
    while True:
        # ask user for response
        user_response = input(prompt)
 
        #if response is response1 or response2 then return
        if user_response == response1 or user_response == response2:
            return user_response
 
 
def print_card(name, num):
    """
    print "______ draws a _____" with the first blank replaced by the user's
    name and the second blank replaced by the value given to the function.
    name (str) - the user name to print out
    num (int) - the number to print out
    """
 
    # if the value is a 1, 11, 12, 13, print Ace, Jack, Queen, King 
    if num == 1:
        num = "Ace"
    elif num == 11:
        num = "Jack"
    elif num == 12:
        num = "Queen"
    elif num == 13:
        num = "King"
    else:
        num = str(num)
 
    # print the string
    print(name, "draws a", num)
         
 
def get_ace_value():
    """
    Ask the user if they want to use a 1 or 11 as their Ace value.
    """
 
    # get the value use "ask_user" function
    value = ask_user("Should the Ace be 1 or 11?", "1", "11")
 
    # retrun the value
    return int(value)
 
 
def deal_card(name):
    """
    Pick a random number between 1 and 13, and print out what the user drew.
    name (str) - the user name to print out
    """
 
    # get a random number in range 1 to 13
    num = random.randrange(1, 13+1)
 
    # use "print_card" function to print out what the user drew
    print_card(name, num)
 
 
    if num > 10:
        # if the card is a Jack, Queen, or King, the point-value is 10
        return 10
    elif num == 1:
        # If the card is an Ace, ask the user if the value should be 1 or 11
        return get_ace_value()
    else:
        return num
         
 
def adjust_for_bust(num):
    """
    If the given number is greater than 21, print "Bust!" and return -1.
    Otherwise return the number that was passed in.
    num (int) - the given number
    """
 
    # determine the value of num
    if num > 21:
        print("Bust!")
        return -1
    else:
        return num
 
 
def hit_or_stay(num):
    """
    Prompt the user hit or stay and return user's chose.
    num (int) - the value of a player's card hand
    """
 
    if num <= 21:
        chose = ask_user("Hit or stay?", "hit", "stay")
        # if num less than 21 and user chose hit return True
        if chose == "hit":
            return True
         
    # otherwise return False
    return False
             
 

def play_turn(name):
    """
    Play whole the trun for a user.
    name (str) - the player's name
    """
 
    # print out that it's the current players turn
    print("==========[ Current player:", name, "]==========")
 
    # set total score zero
    total_score = 0
 
    # deal the player a card for loop
    while True:
 
        # get total score
        total_score += deal_card(name)
 
        # if not busted print out the player's total score
        print("Total:", total_score)
 
 
        # if player chose stay return the result, otherwise continue the loop
        if not hit_or_stay(total_score):
            return adjust_for_bust(total_score)
 
 
 
def determine_winner(name1, name2, score1, score2):
    """
    Determine_the game's winner.
    name1 (str) - the first player's name
    name2 (str) - the second player's name
    score1 (str) - the first player's score
    score2 (str) - the second player's score
    """
 
    if score1 == score2:
        print(name1, "and", name2, "tie!")
    elif score1 > score2:
        print(name1, "wins!")
    elif score1 < score2:
        print(name2, "wins!")
 
 
def main():
    """
    The main program of BlackJack game
    """
 
    while True:
 
        # Ask each player for their name
        name1 = input("Player 1 name:")
        name2 = input("Player 2 name:")
 
        # Greet them
        print("Welcome to BlackJack", name1, "and", name2)
        print()
 
        # Let the first player play a turn
        score1 = play_turn(name1)
        print()
 
        # Let the second player play a turn
        score2 = play_turn(name2)
        print()
 
        # Determine who won
        determine_winner(name1, name2, score1, score2)
 
        # Play again if they say yes and end the loop if they say no
        if ask_user("Would you like to play again?", "yes", "no") == "no":
            break
 
 
if __name__ == "__main__":
    main()

輸出:

Player 1 name:oatmeal
Player 2 name:alice
Welcome to BlackJack oatmeal and alice

==========[ Current player: oatmeal ]==========
oatmeal draws a 9
Total: 9
Hit or stay?hit
oatmeal draws a 3
Total: 12
Hit or stay?hit
oatmeal draws a 2
Total: 14
Hit or stay?stay

==========[ Current player: alice ]==========
alice draws a 9
Total: 9
Hit or stay?hit
alice draws a Jack
Total: 19
Hit or stay?stay

alice wins!
Would you like to play again?yes
Player 1 name:oatmeal
Player 2 name:alice
Welcome to BlackJack oatmeal and alice

==========[ Current player: oatmeal ]==========
oatmeal draws a Ace
Should the Ace be 1 or 11?11
Total: 11
Hit or stay?hit
oatmeal draws a Jack
Total: 21
Hit or stay?stay

==========[ Current player: alice ]==========
alice draws a 9
Total: 9
Hit or stay?hit
alice draws a 2
Total: 11
Hit or stay?hit
alice draws a 6
Total: 17
Hit or stay?hit
alice draws a Ace
Should the Ace be 1 or 11?1
Total: 18
Hit or stay?hit
alice draws a 2
Total: 20
Hit or stay?stay

oatmeal wins!

6. random.randint

而 randint 是怎么用的呢,它可以從參數(shù)指定的范圍里隨機選擇一個整數(shù)返回來。

import random
import time


def open_connection():
    if random.randint(0, 3) != 0:
        raise ValueError
    return True


def connect(nretry=100):
    for _ in range(nretry):
        try:
            if open_connection():
                print("Connected!")
                return
        except ValueError:
            print("failed to connect, note this!")
            time.sleep(2)
            continue

if "__main__" in __name__:
    connect()

在這個程序里, 我們模擬了網(wǎng)絡連接的情況。如果在連接的時候沒有得到正常值,那就等一會兒,然后再連接。
輸出:

failed to connect, note this!
failed to connect, note this!
Connected!

7. random.shuffle()

可以將一個列表里的元素打亂順序重新排列。

import random

def remove_indices(mylist, idxs):
    result = []
    for i, l in enumerate(mylist):
        if i not in idxs:
            result.append(l)
    return result

if "__main__" in __name__:
    name_list = ["xiaopai", "oatmeal", "shuo", "gang"]
    print(name_list)
    random.shuffle(name_list)

    idx_list = []
    for i in range(2):
        Num = input("please enter a number:")
        idx_list.append(int(Num))
    print(name_list)
    win_names = remove_indices(name_list, idx_list)
    print(win_names)

這個在抽簽的時候尤其好用, 備選的人名組成一個列表,然后用 shuffle 把它打亂, 由人再輸入些下標數(shù)值,讓對應下標的人名從列表里被刪掉,看看剩下的人是誰。

輸出:

['xiaopai', 'oatmeal', 'shuo', 'gang']
please enter a number:1
please enter a number:2
['shuo', 'xiaopai', 'gang', 'oatmeal']
['shuo', 'oatmeal']

參考:
random 英文文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容