查看全课大纲(第 37 / 51 节)
  1. 1.为什么人人都该学点编程?
  2. 2.计算机与程序设计:你的电脑到底在“想”什么?
  3. 3.Python 这门语言,到底有什么魔力?
  4. 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
  5. 5.如何安装一个更强大的代码编辑器?
  6. 6.汇率兑换1.0:你的第一个“钱生钱”小程序
  7. 7.你的第一行代码,藏着哪些秘密?
  8. 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
  9. 9.汇率兑换程序,如何让它“聪明”地判断币种?
  10. 10.汇率兑换程序能一直运行,直到我喊停吗?
  11. 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
  12. 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
  13. 13.怎么用 Python 画一个会动的五角星?
  14. 14.如何让程序自动画出不同大小的五角星?
  15. 15.函数自己调用自己,会发生什么?
  16. 16.用递归画出神奇的分形树
  17. 17.Python 怎么计算你一天躺着不动能消耗多少热量?
  18. 18.如何让程序“活”起来,持续为你服务?
  19. 19.如何让 BMR 计算器更“聪明”?
  20. 20.当程序遇到“不按套路出牌”的用户怎么办?
  21. 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
  22. 22.如何用列表记录每一周的存款?
  23. 23.如何让程序自己数数?—— 用 for 循环解放你的双手
  24. 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
  25. 25.52周存钱挑战:怎么根据日期自动查存款?
  26. 26.Python 怎么判断一年中的第几天?
  27. 27.列表 vs 元组:哪个更适合存储月份天数?
  28. 28.用集合给月份分个队,换个思路算天数
  29. 29.把月份和天数“锁”在一起:用字典给数据配个对
  30. 30.Python 怎么判断密码强弱?
  31. 31.Python 怎么给密码设置“防沉迷”系统?
  32. 32.Python 怎么把密码保存到文件里?
  33. 33.Python 怎么读取文件里的密码?
  34. 34.Python 怎么把密码检查工具“打包”起来?
  35. 35.Python 怎么把文件操作也“打包”起来?
  36. 36.计算机怎么“扔骰子”?——用Python模拟随机事件
  37. 37.如何用 Python 模拟掷两个骰子?
  38. 38.怎么用 Python 把骰子轨迹画出来?
  39. 39.骰子点数分布长啥样?用直方图一眼看穿!
  40. 40.用科学计算库让骰子程序“起飞”
  41. 41.空气质量指数怎么算?手把手教你写一个AQI计算器
  42. 42.空气质量指数计算:从零开始,让程序看懂空气
  43. 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
  44. 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
  45. 45.Python 怎么让程序自己判断文件类型?
  46. 46.如何让程序自己上网查空气质量?
  47. 47.用美味的汤来解析网页:Beautiful Soup 入门
  48. 48.如何让爬虫自动抓取全国所有城市的空气质量?
  49. 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
  50. 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
  51. 51.空气质量数据怎么“洗”干净,还能画成图?

如何用 Python 模拟掷两个骰子?

约 10 分钟

小象实战讲义 · Python 入门:8 个小项目边玩边学

上一节我们学会了用 Python 模拟掷一个骰子,并统计了每个点数出现的次数。但玩过飞行棋或大富翁的朋友都知道,很多游戏需要掷两个骰子。这一节,我们就来升级你的程序,让它能同时模拟两个骰子,并看看两个骰子的点数之和有什么有趣的规律!

💡 核心导读

  • 项目升级:从模拟一个骰子,升级到模拟两个骰子。
  • 新知识点:认识 zip() 函数,它像拉链一样,能把两个列表的元素两两配成一对对键值对,再交给 dict() 就能拼成一个字典。
  • 数据结构:当简单的列表无法直接对应结果时,我们请出更灵活的“字典”来帮忙。
  • 有趣发现:两个骰子的点数之和,哪个数字最容易出现?哪个最难?程序会告诉你答案。

从1个到2个:问题升级了

在1.0版本中,我们用一个长度为6的列表,就轻松记录了一个骰子(点数1-6)的出现次数。因为列表的索引(0, 1, 2, 3, 4, 5)正好比点数(1, 2, 3, 4, 5, 6)少1,对应关系很简单。

但现在要掷两个骰子,我们关心的是两个骰子的点数之和。这个和最小是1+1=2,最大是6+6=12。结果范围变成了2到12,一共11种可能。

问题来了:我们还能用一个简单的列表来记录吗?列表的索引是从0开始的,怎么让它对应到2到12的点数和呢?有点麻烦,对不对?

别担心,Python 为我们准备了一个更趁手的工具:字典(Dictionary)。

认识新朋友:字典与 zip() 函数

字典就像一本真正的字典,每个“词条”(键,key)对应一个“解释”(值,value)。在我们的项目里,“词条”就是点数之和(2, 3, 4, …, 12),“解释”就是它出现的次数。

我们可以这样初始化一个字典:

# 笨办法:一个一个写
result_dict = {2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0}

但写11行太累了!有没有更聪明的办法?

有!我们可以先准备好两个列表:

  • 一个列表放所有的“键”(点数之和):[2, 3, 4, ..., 12]
  • 一个列表放所有的“值”(初始次数):[0, 0, 0, ..., 0](11个0)

然后,本节新增的魔法函数 zip() 就登场了!zip() 就像一条拉链,能把两个列表对应位置的元素“扣”在一起,形成一对对“键值对”。

# 看看 zip() 是怎么工作的
keys = [1, 2, 3]
values = ['a', 'b', 'c']
zipped = zip(keys, values)
print(list(zipped))  # 输出:[(1, 'a'), (2, 'b'), (3, 'c')]
[(1, 'a'), (2, 'b'), (3, 'c')]

看,它把 1 和 'a'、2 和 'b' 分别打包成了元组(tuple)。但元组里的元素是不能修改的,而我们需要修改“次数”这个值。所以,我们再用 dict() 函数把这个“元组列表”变成真正的字典:

values = ['a', 'b', 'c']

keys = [1, 2, 3]

my_dict = dict(zip(keys, values))
print(my_dict)  # 输出:{1: 'a', 2: 'b', 3: 'c'}
{1: 'a', 2: 'b', 3: 'c'}

太棒了!现在我们有了一个可以随时修改其中“值”的字典。

动手实现 2.0 版本

思路清晰了,我们来写代码。记住,我们只新增了 zip() 函数和字典的使用,其他部分都是1.0版本的“老朋友”。

import random
random.seed(42)  # 固定随机种子,让示例输出可复现

def roll_dice():
    """
    模拟掷一个骰子
    """
    roll = random.randint(1, 6)
    return roll

def main():
    """
    主函数
    """
    total_times = 10000  # 模拟投掷的总次数

    # 1. 初始化一个全0的列表,长度为11(对应2到12共11种点数之和)
    result_list = [0] * 11

    # 2. 初始化点数列表,范围是2到12
    # 注意:range(2, 13) 会生成 2, 3, 4, ..., 12,不包含13
    point_list = list(range(2, 13))

    # 3. 使用 zip() 和 dict() 创建字典:键是点数,值是初始次数0
    result_dict = dict(zip(point_list, result_list))

    # 4. 开始模拟投掷
    for i in range(total_times):
        # 掷第一个骰子
        roll1 = roll_dice()
        # 掷第二个骰子
        roll2 = roll_dice()
        # 计算点数之和
        sum_of_points = roll1 + roll2

        # 5. 在字典中对应的点数之和上增加一次计数
        # 这里非常直接:点数之和 sum_of_points 就是字典的键
        result_dict[sum_of_points] += 1

    # 6. 输出结果
    print(f'模拟投掷两个骰子 {total_times} 次,结果如下:')
    for point, count in result_dict.items():  # .items() 可以同时取出键和值
        frequency = count / total_times
        print(f'点数{point}的次数:{count},频率:{frequency:.3f}')  # :.3f 保留3位小数

# 运行主程序
main()

运行上面的代码,你会看到下面的输出(代码固定了 random.seed(42),所以你运行会得到完全相同的数字;删掉这一行才会每次随机变化,但无论怎么变,下面这条“7 最多、2 和 12 最少”的规律都一致):

模拟投掷两个骰子 10000 次,结果如下:
点数2的次数:270,频率:0.027
点数3的次数:540,频率:0.054
点数4的次数:816,频率:0.082
点数5的次数:1094,频率:0.109
点数6的次数:1359,频率:0.136
点数7的次数:1704,频率:0.170
点数8的次数:1392,频率:0.139
点数9的次数:1116,频率:0.112
点数10的次数:838,频率:0.084
点数11的次数:560,频率:0.056
点数12的次数:311,频率:0.031

发现有趣的规律

看输出结果!你发现什么了吗?

  • 点数7出现的次数最多,频率最高(接近16.7%)。这很符合概率规律,因为两个骰子组合出7的方式最多(1+6, 2+5, 3+4, 4+3, 5+2, 6+1),有6种组合。
  • 点数2和12出现的次数最少。因为它们各自只有一种组合方式(1+1 和 6+6)。
  • 整体分布呈一个对称的“山峰”形状,中间高,两边低。

是不是很酷?我们不仅用程序模拟了游戏场景,还直观地验证了概率知识。字典的引入,让我们能轻松处理这种“键”不连续(2到12)的统计问题,比硬用列表方便多了。

📝 动手练一练

  1. 改变命运? 将代码中的 total_times 从 10000 改为 1000 次再运行,观察频率(尤其是点数7的频率)变化大吗?这说明了“大数定律”的什么特点?
  2. 挑战三个骰子! 如果我想模拟掷三个骰子,统计点数之和(3到18)的情况。按照本节课的思路,我需要初始化一个多长的列表?point_list 应该用 range(?, ?) 来生成?试着修改代码实现它。
👉 点击查看参考答案
  1. 思路:将 total_times 改小后运行,会发现各点数的频率波动变大,可能不那么接近理论概率了。这说明实验次数越多,统计结果越稳定,越接近真实概率。
# 只需修改 main() 函数中的一行
total_times = 1000  # 改为1000次
  1. 思路:三个骰子,点数之和最小为3(1+1+1),最大为18(6+6+6)。共有 18-3+1 = 16 种可能。
    • 初始化列表长度应为16。
    • point_list = list(range(3, 19)) # 生成3到18的列表
    • 同时需要掷三次骰子,并计算三个点数之和。
# 关键修改部分的代码片段
def main():
    total_times = 10000
    # 16种可能,从3到18
    result_list = [0] * 16
    point_list = list(range(3, 19))
    result_dict = dict(zip(point_list, result_list))

    for i in range(total_times):
        roll1 = roll_dice()
        roll2 = roll_dice()
        roll3 = roll_dice()  # 新增第三个骰子
        sum_of_points = roll1 + roll2 + roll3
        result_dict[sum_of_points] += 1
    # ... 后续输出代码不变
运行后你会发现,分布的山峰会更集中在中间(比如10或11附近)。

本章小结

恭喜!你的“掷骰子模拟器”成功升级到了2.0版本,现在它能处理更复杂的双骰子游戏了。

📋 行动清单

  • 运行代码,观察两个骰子点数之和的分布,记住7是最常见的点数。
  • 理解 zip():在脑子里想象它像拉链一样合并两个列表的过程。
  • 区分列表和字典:问自己,什么时候该用列表(索引连续),什么时候该用字典(键值对应更自由)?

—— 小象教研组

配套资料 · 直接下载

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

  • 第8章代码包:模拟掷骰子(含全部版本 5 个 .py)
    ZIP · 3KB
    下载
看图文没弄懂?展开看本节视频讲解(约 10 分钟)
📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)