【问题标题】:Updating dictionary with randint performing unexpectedly使用 randint 更新字典时意外执行
【发布时间】:2014-05-15 18:40:56
【问题描述】:

我正在尝试运行一个简单的程序,在该程序中我试图在循环中运行random.randint() 以更新字典值,但它似乎工作不正确。它似乎总是产生相同的价值。

到目前为止的程序如下。我正在尝试创建一个均匀分布的人口,但我不确定为什么这不起作用。

import random

__author__ = 'navin'

namelist={
"person1":{"age":23,"region":1},
"person2":{"age":24,"region":2},
"person3":{"age":25,"region":0}
}

def testfunction():
    default_val={"age":23,"region":1}
    for i in xrange(100):
        namelist[i]=default_val
    for index in namelist:
        x = random.randint(0, 2)
        namelist[index]['region']=x

    print namelist


if __name__ == "__main__" :
    testfunction()

我预计这 103 人大致均匀分布在区域 0-2 中,但我将每个人都放在区域 0 中。

知道为什么会这样吗?我是否错误地使用了randint

【问题讨论】:

    标签: python random dictionary


    【解决方案1】:

    这是因为在 for 循环中创建的所有 100 个字典条目不仅引用了相同的值,而且引用了相同的对象。因此,只有 4 个不同的字典作为值 - 最初创建的 3 个和您使用键 0-99 添加 100 次的第四个。

    这可以通过 id() 函数来演示,该函数为每个不同的对象返回不同的整数:

    from collections import Counter
    
    ...
    
    ids = [ id(i) for i in namelist.values() ]
    print Counter(ids)
    

    结果:

    Counter({139830514626640: 100, 139830514505160: 1, 
        139830514504880: 1, 139830514505440: 1})
    

    要获得不同的字典,您需要复制默认值:

    namelist[i] = default_val.copy()
    

    或者在每个循环上创建一个新字典

    namelist[i] = {"age": 23, "region": 1}
    

    【讨论】:

    • 非常感谢....我现在觉得自己完全是个白痴,因为没有意识到这一点! :|再次感谢:D
    【解决方案2】:
    default_val={"age":23,"region":1}
    for i in xrange(100):
        namelist[i]=default_val
    

    这并不意味着“将每个条目设置为具有这些特定年龄和地区值的字典”。这意味着“将每个条目设置为此特定字典对象”。

    for index in namelist:
        x = random.randint(0, 2)
        namelist[index]['region']=x
    

    由于namelist 中的每个对象实际上都是同一个字典,因此此循环中的所有修改都发生在同一个字典中,x 的最后一个值会擦除其他对象。

    评估一个dict字面量会创建一个新的dict;分配没有。如果你想每次都制作一个新字典,请将字典文字放入循环中:

    for i in xrange(100):
        namelist[i]={"age":23,"region":1}
    

    【讨论】:

      【解决方案3】:

      想将此添加为评论,但链接太长。正如其他人所说,您刚刚分享了对字典的引用,如果您想查看可视化效果,可以在 Python Tutor 上查看它,它应该可以帮助您了解正在发生的事情。

      【讨论】:

        猜你喜欢
        • 2021-07-08
        • 2022-08-22
        • 1970-01-01
        • 1970-01-01
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多