查看全课大纲(第 49 / 51 节)
  1. 1.Python 是什么?为什么值得学?
  2. 2.如何为 Python 编程准备一个“全家桶”环境?
  3. 3.Python 有哪几种执行方法?
  4. 4.行与缩进到底有什么用?
  5. 5.注释有什么用,怎么写?
  6. 6.变量:如何给数据起个好名字?
  7. 7.运算符的优先级和常见坑点是什么?
  8. 8.Python 中,数字和布尔值究竟有哪几种?
  9. 9.输入函数 `input()` 和文件读取 `open()` 怎么用?
  10. 10.如何将程序的结果展示给用户或保存下来?
  11. 11.CSV 文件怎么读怎么写才方便?
  12. 12.列表是什么,如何创建和访问它?
  13. 13.列表的修改操作,有哪些方法?
  14. 14.列表切片为什么能取到部分元素?排序和查找又该怎么用?
  15. 15.判断语句:如何让程序根据条件做不同的事?
  16. 16.for 循环如何遍历序列中的元素?
  17. 17.while 循环什么时候才会停?
  18. 18.while 循环的结束条件,你写对了吗?
  19. 19.循环中途想提前结束,怎么办?
  20. 20.`break` 和 `continue` 到底有什么区别?
  21. 21.列表推导式如何让代码更简洁高效?
  22. 22.字符串怎么定义、拼接和操作?
  23. 23.元组:为什么定义单个元素时要加逗号?
  24. 24.集合(set)怎么用?如何快速去重和做集合运算?
  25. 25.字典是什么,为什么比列表更方便?
  26. 26.字典的增删改查与遍历,如何避免 KeyError?
  27. 27.函数里的变量,为什么有的能用有的不能用?
  28. 28.在函数内部修改全局变量,为什么有时不生效?
  29. 29.函数里能修改全局变量吗?返回值怎么用?
  30. 30.匿名函数:如何用 lambda 快速定义简单函数?
  31. 31.面向对象编程是什么,为什么需要它?
  32. 32.类中的方法和属性到底怎么定义和使用?
  33. 33.如何控制对对象内部属性和方法的访问?
  34. 34.异常发生时,程序会怎样继续执行?
  35. 35.如何组织代码:包和模块
  36. 36.`if __name__ == '__main__'` 到底有什么用?
  37. 37.如何用 IDE 的 Debug 功能排查程序错误?
  38. 38.Matplotlib 绘图的第一步该做什么?
  39. 39.Figure 是什么,如何设置图形尺寸?
  40. 40.如何自定义 Matplotlib 的坐标轴?
  41. 41.如何为图表添加图例,让不同曲线一目了然?
  42. 42.饼图怎么画才能直观展示数据占比?
  43. 43.如何用 Matplotlib 绘制散点图?
  44. 44.柱状图怎么画?
  45. 45.如何使用 Matplotlib 绘制等高线图?
  46. 46.如何在 Matplotlib 中绘制子图?
  47. 47.zip 函数如何把多个列表“打包”在一起?
  48. 48.如何给可迭代对象加上索引?
  49. 49.random 模块如何生成随机数?
  50. 50.math 模块怎么用?
  51. 51.Counter 如何快速统计元素出现次数?

random 模块如何生成随机数?

约 5 分钟

小象实战讲义 · Python 编程从入门到实践

做抽奖、游戏、随机排序时,程序都需要“不确定性”。Python 标准库中的 random 模块就是用来产生随机数的,它提供了生成随机小数、随机整数、随机挑选和打乱序列等常用函数。本节是第 6 章《一些常用的函数》的第 3 节,学完你就能根据需求选对函数,并避开常见的参数错误。

💡 核心导读

  • 导入:使用前先 import random。
  • 随机小数:random.random() 生成 0.0 到 1.0 之间的小数;random.uniform(a, b) 生成 a 到 b 之间的小数。
  • 随机整数:random.randint(a, b) 生成 a 到 b 之间的整数(包含两端);random.randrange(start, stop, step) 按步长取整数。
  • 选择与打乱:random.choice(seq) 随机选一个元素;random.shuffle(seq) 原地打乱;random.sample(seq, k) 抽取 k 个不重复元素。

生成随机小数

使用 random 模块的第一步是导入它。导入后,调用模块里的 random() 函数,就能得到一个 0.0 到 1.0 之间的小数:

import random

random.seed(42)  # 固定随机种子,让每次运行的输出一致,便于对照
print(random.random())          # 0.0 到 1.0 之间的小数
print(random.uniform(1, 10))    # 1 到 10 之间的小数
0.6394267984578837
1.2250967970040025

random.random() 不需要参数。random.uniform(a, b) 接收两个参数,分别表示下限和上限,返回 a 到 b 之间的随机浮点数。

关于种子:本节示例统一写了 random.seed(42),这样每次运行得到的结果都相同,方便你对照输出。真实项目里通常不需要固定种子,去掉这一行,每次运行就会得到不同的随机值。

生成随机整数

random.randint(a, b) 生成 a 到 b 之间的随机整数,并且包含两端的 a 和 b。所以 randint(1, 2) 的结果可能是 1,也可能是 2。

random.randrange(start, stop, step) 的用法类似 range():在 [start, stop) 范围内按 step 步长取一个随机整数,不包含 stop。

import random

random.seed(42)
print(random.randint(1, 10))      # 1 到 10,包含两端
print(random.randint(1, 2))       # 只可能是 1 或 2

print(random.randrange(0, 20, 2)) # 0 到 20 之间的随机偶数
print(random.randrange(0, 20, 3)) # 0 到 20 之间能被 3 整除的数
2
1
8
3

三个参数的含义分别是:start 起始值(包含)、stop 结束值(不包含)、step 步长。结果是 start、start + step、start + 2 * step 这样一串数中的一个,并且小于 stop。上例的 start 是 0,所以步长设为 3 时,结果就是 0、3、6、9、12、15、18 中的一个。

随机选择与序列操作

random.choice(seq) 从一个非空序列中随机取一个元素,字符串、列表都可以。random.shuffle(x) 把传入的可变序列(通常是列表)原地打乱,函数本身返回 None。random.sample(population, k) 从序列中随机抽取 k 个不重复的元素,返回一个新列表。

import random

random.seed(42)
# 从字符串中随机取一个字符
print(random.choice('HelloWorld'))

# 从列表中随机取一个元素
fruits = ['苹果', '香蕉', '橙子', '葡萄']
print(random.choice(fruits))

# shuffle 原地打乱列表,返回值是 None
items = [1, 2, 3, 4, 5, 6, 7]
random.shuffle(items)
print('打乱后的列表:', items)

# sample 抽取 3 个不重复的元素
sampled = random.sample([1, 2, 3, 4, 5], 3)
print('抽取的样本:', sampled)
e
苹果
打乱后的列表: [4, 7, 1, 5, 2, 3, 6]
抽取的样本: [5, 1, 3]

sample 的第二个参数 k 不能大于序列长度,否则会抛出 ValueError。

📝 动手练一练

  1. 抽奖名单是 ['张三', '李四', '王五', '赵六', '钱七'],请随机抽取一名一等奖和两名二等奖(二等奖之间不能重复,也不能与一等奖重复)。
👉 点击查看参考答案

思路:先用 random.choice 抽一等奖,再从名单里去掉一等奖得主,用 random.sample 抽两名不重复的二等奖。

import random
random.seed(42)
participants = ['张三', '李四', '王五', '赵六', '钱七']
first_prize = random.choice(participants)
print('一等奖获得者:{}'.format(first_prize))
remaining = [p for p in participants if p != first_prize]
print('二等奖获得者:{}'.format(random.sample(remaining, 2)))
一等奖获得者:张三
二等奖获得者:['李四', '赵六']
  1. 用 random 模块生成一个由 6 位数字组成的随机验证码。
👉 点击查看参考答案

思路:准备 0 到 9 的数字字符串,循环 6 次,每次用 random.choice 取一个字符拼起来。choice 允许重复,正好符合验证码的要求。

import random
random.seed(42)
digits = '0123456789'
code = ''
for _ in range(6):
    code += random.choice(digits)
print('生成的验证码:{}'.format(code))
生成的验证码:104332

常见错误

错误写法现象或报错原因正确写法
random.randint(1, 10.5)TypeError: 'float' object cannot be interpreted as an integerrandint 的两个参数必须是整数random.randint(1, 10)
random.choice([])IndexError: Cannot choose from an empty sequencechoice 要求序列非空先确认序列至少有一个元素
random.sample([1, 2, 3], 5)ValueError: Sample larger than population or is negative抽样数量 k 不能大于序列长度random.sample([1, 2, 3], 3)
result = random.shuffle(lst)result 是 None,并没有拿到打乱后的列表shuffle 原地修改,不返回新列表random.shuffle(lst) 后直接打印 lst

小结

  1. 使用前先 import random;示例用 random.seed(42) 固定结果,真实场景可去掉。
  2. random.random() 生成 0.0 到 1.0 之间的小数,random.uniform(a, b) 生成 a 到 b 之间的小数。
  3. random.randint(a, b) 包含两端;random.randrange(start, stop, step) 不包含 stop,可按步长取值。
  4. random.choice(seq) 随机选一个元素,序列不能为空。
  5. random.shuffle(seq) 原地打乱可变序列,返回 None。
  6. random.sample(seq, k) 抽取 k 个不重复元素,返回新列表,k 不能大于序列长度。

📋 行动清单

  • 把示例中的 random.seed(42) 注释掉,连续运行几次,观察结果的变化。
  • 用 randint(1, 6) 模拟掷骰子,连掷 10 次并打印结果。
  • 准备一个含 10 个单词的列表,用 sample 随机抽出 3 个,拼成一句话。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第6章代码包:random(含1 个 Notebook)
    ZIP · 707B
    下载