從 Python 列表中隨機選擇元素的選擇、樣本和選擇。

商業

Python 標準庫的 random 模塊中的choice()、sample() 和choices() 函數可用於從列表、元組、字符串或其他序列對象(隨機抽樣)中隨機選擇和檢索元素。

choice() 獲取單個元素, sample() 和choices() 獲取多個元素的列表。 sample() 是不可恢復的提取,沒有重複,choices() 是可恢復的提取,有重複。

此處提供了以下信息。

  • 隨機選擇一個元素。:random.choice()
  • 隨機選擇多個元素(不重複):random.sample()
  • 隨機選擇多個元素(有重複項):random.choices()
  • 修復隨機數種子

隨機選擇一個元素。:random.choice()

使用 random 模塊的函數 choose(),從列表中隨機選擇一個元素並可以檢索。

import random

l = [0, 1, 2, 3, 4]

print(random.choice(l))
# 1

這同樣適用於元組和字符串。在字符串的情況下,選擇單個字符。

print(random.choice(('xxx', 'yyy', 'zzz')))
# yyy

print(random.choice('abcde'))
# b

如果將空列表、元組或字符串指定為參數,則會出錯。

# print(random.choice([]))
# IndexError: Cannot choose from an empty sequence

隨機選擇多個元素(不重複):random.sample()

使用 random 模塊的函數 sample(),您可以從列表中隨機獲取多個元素。沒有重複的元素(不可恢復的提取)。

第一個參數是一個列表,第二個參數是要檢索的元素數。返回列表。

import random

l = [0, 1, 2, 3, 4]

print(random.sample(l, 3))
# [2, 4, 0]

print(type(random.sample(l, 3)))
# <class 'list'>

如果第二個參數設置為 1,則還返回一個包含一個元素的列表;如果設置為 0,則列表為空。如果第二個參數為 1,則返回一個包含一個元素的列表;如果為0,則返回一個空列表;如果第一個參數大於列表中元素的數量,則會發生錯誤。

print(random.sample(l, 1))
# [3]

print(random.sample(l, 0))
# []

# print(random.sample(l, 10))
# ValueError: Sample larger than population or is negative

如果第一個參數是元組或字符串,則返回的仍然是列表。

print(random.sample(('xxx', 'yyy', 'zzz'), 2))
# ['xxx', 'yyy']

print(random.sample('abcde', 2))
# ['b', 'e']

如果要返回元組或字符串,請使用 tuple(),join()。

print(tuple(random.sample(('xxx', 'yyy', 'zzz'), 2)))
# ('xxx', 'yyy')

print(''.join(random.sample('abcde', 2)))
# dc

注意不判斷值,所以如果原始列表或元組包含具有相同值的元素,則有可能會選擇相同的值。

l_dup = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]

print(random.sample(l_dup, 3))
# [3, 1, 1]

如果要避免重複值,可以使用 set() 將其轉換為集合(集合類型)並僅提取唯一元素,然後使用 sample()。

print(set(l_dup))
# {0, 1, 2, 3}

print(random.sample(set(l_dup), 3))
# [1, 3, 2]

隨機選擇多個元素(有重複項):random.choices()

random 模塊的函數choices() 允許您從列表中隨機檢索多個元素,並且與sample() 不同,它允許選擇重複的元素。

Choices() 是 Python 3.6 中添加的函數。它在早期版本中不可用。

參數 k 指定要檢索的元素的數量。允許重複,因此要檢索的元素數可以大於原始列表中的元素數。

由於 k 是僅關鍵字參數,因此需要指定關鍵字,例如 k=3。

import random

l = [0, 1, 2, 3, 4]

print(random.choices(l, k=3))
# [2, 1, 0]

print(random.choices(l, k=10))
# [3, 4, 1, 4, 4, 2, 0, 4, 2, 0]

k的默認值為1;如果省略,則返回一個包含 1 個元素的列表。

print(random.choices(l))
# [1]

參數 weights 可用於指定每個元素將被選中的權重(概率),列表中元素的類型可以是 int 或 float。

print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1]))
# [0, 2, 3]

print(random.choices(l, k=3, weights=[1, 1, 0, 0, 0]))
# [0, 1, 1]

參數 cum_weights 也可以指定為累積權重。以下示例代碼中的 cum_weights 等效於上面的第一個權重。

print(random.choices(l, k=3, cum_weights=[1, 2, 3, 13, 14]))
# [3, 2, 3]

參數 weights 和 cum_weights 的默認值為 None,這意味著每個元素以相同的概率被選擇。

如果參數 weights 或 cum_weights 的長度(元素數)與原始列表不同,則會發生錯誤。

# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1, 1, 1]))
# ValueError: The number of weights does not match the population_

同時指定 weights 和 cum_weights 也是錯誤的。

# print(random.choices(l, k=3, weights=[1, 1, 1, 10, 1], cum_weights=[1, 2, 3, 13, 14]))
# TypeError: Cannot specify both weights and cumulative weights

到目前為止,我們已將列表指定為第一個參數作為示例代碼中的示例,但同樣適用於元組和字符串。

修復隨機數種子

通過給隨機模塊的函數seed()一個任意整數,可以固定隨機數種子並且可以初始化隨機數生成器。

用相同的種子初始化後,總是以相同的方式選擇元素。

random.seed(0)
print(random.choice(l))
# 3

random.seed(0)
print(random.choice(l))
# 3