100囚犯问题Python代码异常:每次运行均17人成功求排查
100囚犯问题代码错误排查与修正
问题根源:变量作用域错误
你的代码中begin函数内定义的prisoners和boxes是局部变量,run函数无法访问这些每次随机生成的新值。实际运行时,run函数使用的是全局环境中未更新的旧变量(或首次运行会直接报错),这就是为什么每次得到固定17名囚犯成功的异常结果。
修正后的代码
import random def begin(p=False): prisoners = list(range(100)) boxes = prisoners.copy() random.shuffle(boxes) # 索引代表盒子编号,值代表盒子内的编号 if p: for idx, num in enumerate(boxes): print(f"盒子{idx}内的编号:{num}") return prisoners, boxes # 返回生成的囚犯列表和打乱后的盒子列表 def run(prisoners, boxes, p=True): results = {"Success": False, "NumSucceed": 0, "NumFail": 0} for prisoner in prisoners: fail = True current_choice = boxes[prisoner] # 第一步:打开标有自己编号的盒子 # 总共50次机会,已经用了1次,剩余49次尝试 for _ in range(49): if current_choice == prisoner: fail = False break current_choice = boxes[current_choice] # 检查第一次尝试是否直接成功(循环没执行的情况) if current_choice == prisoner: fail = False if fail: results["NumFail"] += 1 else: results["NumSucceed"] += 1 results["Success"] = (results["NumSucceed"] == 100) if p: print(results) return results # 运行100次模拟 for i in range(100): prisoners_list, boxes_list = begin() run(prisoners_list, boxes_list)
关键修改说明
- 变量传递:
begin函数返回生成的prisoners和boxes,run函数通过参数接收这些最新的随机数据,确保每次模拟使用的都是当前打乱后的盒子。 - 逻辑补全:新增了对第一次尝试直接成功的判断(如果第一次打开的盒子就是自己的编号,循环不会执行,需要单独确认)。
- 命名优化:将
choice改为current_choice,提升代码可读性。 - 去除全局依赖:避免函数依赖全局变量,保证代码的独立性和可复用性。
修正后运行代码,就能得到符合预期的概率结果(整体成功率约30%左右)。
内容的提问来源于stack exchange,提问作者Arjun
相关产品推荐
相关产品推荐

