随机性到处都是。 当您掷硬币或掷骰子时,您永远无法确定最终结果。 这种不可预测性具有许多应用程序,例如确定幸运抽奖的获胜者或为具有基于算法产生的随机值的实验生成测试用例。
牢记这一用处,Python为我们提供了random模块。 您可以在游戏中使用它随机产生敌人或随机播放列表中的元素。
随机如何工作?
此模块中几乎所有函数都依赖于基本random()
函数,该函数将生成一个大于或等于零且小于一的随机浮点数。 Python使用Mersenne Twister生成浮点数。 它产生周期为2 ** 19937-1的53位精度浮点数。 实际上,它是使用最广泛的通用伪随机数生成器。
有时,您希望随机数生成器重现它第一次创建的数字序列。 这可以通过使用seed(s, version)
函数seed(s, version)
两次向生成器提供相同的种子值来实现。 如果省略参数s ,则生成器将使用当前系统时间生成数字。 这是一个例子:
import random
random.seed(100)
random.random()
# returns 0.1456692551041303
random.random()
# returns 0.45492700451402135
请记住,与硬币翻转不同,该模块生成完全确定性的伪随机数,因此不适合用于加密目的。
产生随机整数
该模块具有两个不同的函数,用于生成随机整数。 您可以使用randrange(a)
生成一个随机整数小于a
。
同样,您可以使用randrange(a, b[,step])
从range(a, b, step)
生成一个随机数。 例如,使用random.randrange(0, 100, 3)
将只返回0到100之间的数字,这些数字也可以被3整除。
如果您知道要生成数字的上下限,则可以使用一个更简单,更直观的函数randint(a, b)
。 它只是randrange(a, b+1)
的别名。
import random
random.randrange(100)
# returns 65
random.randrange(100)
# returns 98
random.randrange(0, 100, 3)
# returns 33
random.randrange(0, 100, 3)
# returns 75
random.randint(1,6)
# returns 4
random.randint(1,6)
# returns 6
序列功能
要从给定的非空序列中选择一个随机元素,可以使用choice(seq)
函数。 使用randint()
,您只能选择给定范围内的数字。 choice(seq)
函数允许您从所需的任何序列中选择一个数字。
此功能的另一个好处是它不仅限于数字。 它可以从序列中随机选择任何类型的元素。 例如,可以使用此功能轻松确定以字符串形式提供的五个不同人之间的幸运抽奖获胜者的姓名。
如果要随机播放序列而不是从中选择随机元素,则可以使用shuffle(seq)
函数。 这将导致序列的就地改组。 对于仅包含10(n)个元素的序列,总共可以有3628800(n!)个不同的排列。 对于较大的序列,可能的排列数量将更高—这意味着该函数永远不会生成较大序列的所有排列。
假设您必须从100名学生中选出50名学生去旅行。
此时,您可能会喜欢使用choice(seq)
函数。 问题是,在最佳情况下,您将不得不调用它大约50次,因为这样就不会再次选择同一名学生。
更好的解决方案是使用sample(seq, k)
函数。 它将返回给定序列中k个唯一元素的列表。 原始序列保持不变。 结果列表中的元素将按选择顺序。 如果k大于序列本身中的元素数,则将引发ValueError 。
import random
ids = [1, 8, 10, 12, 15, 17, 25]
random.choice(ids) # returns 8
random.choice(ids) # returns 15
names = ['Tom', 'Harry', 'Andrew', 'Robert']
random.choice(names) # returns Tom
random.choice(names) # returns Robert
random.shuffle(names)
names
# returns ['Robert', 'Andrew', 'Tom', 'Harry']
random.sample(names, 2)
# returns ['Andrew', 'Robert']
random.sample(names, 2)
# returns ['Tom', 'Robert']
names
# returns ['Robert', 'Andrew', 'Tom', 'Harry']
如您所见, shuffle(seq)
修改了原始列表,但sample(seq, k)
保持了原样。
产生随机浮动
在本节中,您将学习可用于基于特定实值分布生成随机数的函数。 这些函数中大多数函数的参数都以该分布的实际方程式中的相应变量命名。
当您只想要0到1之间的数字时,可以使用random()
函数。 如果您希望数字在特定范围内,则可以将uniform(a, b)
函数与a和b分别用作下限和上限。
假设您需要生成一个介于低数和高数之间的随机数,以使其更有可能位于另一个数字模式附近。 您可以使用triangular(low, high, mode)
功能执行此triangular(low, high, mode)
。 默认情况下, 低值和高值将为0和1。 同样, 模式值默认为低值和高值的中点,导致对称分布。
还有很多其他功能可以根据不同的分布生成随机数。 例如,您可以使用normalvariate(mu, sigma)
基于正态分布生成一个随机数,其中mu为均值, sigma为标准差。
import random
random.random()
# returns 0.8053547502449923
random.random()
# returns 0.05966180559620815
random.uniform(1, 20)
# returns 11.970525425108205
random.uniform(1, 20)
# returns 7.731292430291898
random.triangular(1, 100, 80)
# returns 42.328674062298816
random.triangular(1, 100, 80)
# returns 73.54693076132074
加权概率
如我们所见,可以生成具有均匀分布以及三角形或正态分布的随机数。 即使在0到100这样的有限范围内,也可以生成无限数量的浮点数。 如果元素有限,又想在选择随机数的同时为某些特定值增加权重,该怎么办? 这种情况在彩票系统中很常见,在这种系统中,奖励很少的数字具有较高的权重。
如果应用程序的权重为整数值是可接受的,则可以创建一个元素列表,其频率取决于其权重。 然后,您可以使用choice(seq)
函数从该加权列表中随机选择一个元素。 这是示出随机选择奖金额的示例。
import random
w_prizes = [('$1', 300), ('$2', 50), ('$10', 5), ('$100', 1)]
prize_list = [prize for prize, weight in w_prizes for i in range(weight)]
random.choice(prize_list)
# returns '$1'
以我为例,经过十次尝试,才从列表中选择了2美元的奖金。 获得100美元奖金的机会要低得多。 同样,您也可以为其他此类程序增加偏见。
最后的想法
该模块在许多情况下都非常有用,例如将作业中的问题改组或通过使用shuffle()
函数为用户生成随机的用户名或密码。 您还可以统一生成随机数,也可以对特定范围内的数字进行加权。 在我们的下一个教程中,我们将使用该模块中的函数来生成随机数据以进行统计分析。
您是否想到了一些有趣的随机数生成器应用程序,这些应用程序可能对其他读者有用? 让我们在评论中知道。
翻译自: https://code.tutsplus.com/tutorials/mathematical-modules-in-python-random--cms-27738