You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何random.choice选择结果严重失衡?技术咨询

问题分析与解决方案

这个问题的核心是你不小心修改了实例的持久化属性self.l,而且在每次调用get()方法时反复添加e和f,导致它们在候选列表中的占比越来越高,最终几乎垄断了随机选择结果。

问题根源拆解

我们一步步看代码的执行逻辑:

  1. 初始化a = A("+abcd")后,self.l被设置为["a", "b", "c", "d"],这一步是正常的。
  2. 重点看get()方法的实现:
    def get(self, l):
        rt = self.l
        if self.include:
            rt += l
        return choice(rt)
    
    • rt = self.l这行是引用赋值,不是创建新列表。也就是说rt和self.l指向内存中的同一个列表对象。
    • 当执行rt += l时,因为列表是可变对象,这个操作会直接修改原列表(也就是self.l),而不是创建新的列表。

所以第一次调用a.get(["e","f"])后,self.l变成了["a","b","c","d","e","f"];第二次调用时,又往里面追加了["e","f"],变成["a","b","c","d","e","f","e","f"];循环10万次后,self.l里e和f的数量已经达到几十万级,而a/b/c/d始终只有各1个,随机选中它们的概率自然微乎其微。

修复方案

只需要在get()方法中创建self.l的副本,避免修改原属性即可。修改后的get()方法如下:

def get(self, l):
    rt = list(self.l)  # 或者用 self.l.copy(),创建原列表的独立副本
    if self.include:
        rt += l
    return choice(rt)

这样每次rt都是一个全新的列表,修改它不会影响self.l,每次随机选择的候选列表都是固定的["a","b","c","d","e","f"],10万次循环后,各个元素的分布就会接近你预期的均匀状态。

补充提示

这是Python中可变对象(列表、字典、集合等)的常见陷阱:赋值操作传递的是对象引用而非副本,修改赋值后的变量会直接影响原对象。如果需要操作对象的副本,一定要显式创建(比如list(obj)、obj.copy()等方式)。

内容的提问来源于stack exchange,提问作者GT 77

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:37:52