使用randint意外执行更新字典

时间:2014-05-15 18:40:57

标签: python random dictionary

我试图运行一个简单的程序,我试图在循环中运行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

3 个答案:

答案 0 :(得分:4)

这是因为在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}

答案 1 :(得分: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}

答案 2 :(得分:1)

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