如何让randint/random.choice/random.sample每9次选择中指定数字出现固定次数?
实现方案
方法一:预生成符合规则的随机序列(推荐)
这种方法先一次性生成满足要求的9个数字列表,再遍历执行,逻辑简单且能100%确保达标,无需回溯调整。
核心思路
- 先随机生成3个属于{3,4,5}的数字,对应要求的总出现次数
- 再随机生成6个非{3,4,5}的数字(即1、2、6-16),填充剩余位置
- 将两组数字合并后打乱顺序,保证随机性
- 遍历打乱后的序列执行对应动作
代码示例
import random frames = [frame1, frame2, frame3, frame4, frame5, frame6, frame7, frame8, frame9] letter_list = [] # 生成符合要求的x序列 required_count = 3 total_frames = 9 # 生成3个3/4/5的随机数 required_nums = [random.choice([3,4,5]) for _ in range(required_count)] # 生成6个非3/4/5的随机数(1,2,6-16) other_nums = [random.choice([1,2] + list(range(6,17))) for _ in range(total_frames - required_count)] # 合并并打乱顺序 x_sequence = required_nums + other_nums random.shuffle(x_sequence) # 遍历执行动作 for x in x_sequence: if x == 1: d1 = Ds(1) letter_list.append("d1") elif x == 2: d2 = Ds(0, 1) letter_list.append("d2") elif x == 3: d3 = Ds(1, 1) letter_list.append("d3") elif x == 4: d4 = Ds(2) letter_list.append("d4") elif x == 5: d5 = Ds(0, 2) letter_list.append("d5") # 补充6-16对应的动作逻辑(根据你的实际需求添加)
方法二:动态跟踪+实时调整
这种方法在循环过程中实时统计3/4/5的出现次数,根据剩余帧数动态调整可选数字范围,确保最终总次数达标。
核心思路
- 初始化计数器,跟踪3/4/5的当前出现次数
- 每轮循环计算剩余帧数和还需满足的次数:
- 若已达标,只能选非3/4/5的数字
- 若剩余帧数不足以凑够所需次数,强制选3/4/5
- 其他情况可选所有数字,靠后续循环自动平衡
- 执行动作并更新计数器
代码示例
import random frames = [frame1, frame2, frame3, frame4, frame5, frame6, frame7, frame8, frame9] letter_list = [] required_total = 3 current_count = 0 total_frames = len(frames) for idx, item in enumerate(frames): remaining_frames = total_frames - idx - 1 remaining_needed = required_total - current_count # 动态确定可选数字范围 if remaining_needed == 0: # 已达标,仅允许选非3/4/5的数字 available = [1,2] + list(range(6,17)) elif remaining_needed > remaining_frames: # 剩余帧数不够,必须选3/4/5 available = [3,4,5] else: # 可选所有数字,后续会自动平衡次数 available = list(range(1,17)) x = random.choice(available) # 更新3/4/5的出现次数 if x in [3,4,5]: current_count += 1 # 执行对应动作 if x == 1: d1 = Ds(1) letter_list.append("d1") elif x == 2: d2 = Ds(0, 1) letter_list.append("d2") elif x == 3: d3 = Ds(1, 1) letter_list.append("d3") elif x == 4: d4 = Ds(2) letter_list.append("d4") elif x == 5: d5 = Ds(0, 2) letter_list.append("d5") # 补充6-16对应的动作逻辑(根据你的实际需求添加)
两种方法对比
- 方法一:逻辑简单、性能高,随机性均匀,适合大多数场景
- 方法二:无需提前生成序列,适合需要边循环边处理的动态场景
内容的提问来源于stack exchange,提问作者lasketse12
相关产品推荐
相关产品推荐

