奇怪的额外循环

时间:2012-10-22 18:00:01

标签: python python-3.x

我对Python仍然有些新意,但是,我现在感觉真的愚蠢'因为我只花了一个小时试图找出为什么这个for循环没有做什么我想要。我不应该在for循环上花一个小时。无论如何,我正在尝试生成一个字典列表,并给每个字典一个唯一的编号,所以我这样做...

def initiate(n):
    records = {'num':0,'blah':0,'doubleblah':0}
    x = []
    for i in range(n):
        x.append(records)
        x[i]['num'] = i
    return x

x = initiate(4)
print(x)

我希望函数返回 -

[
 {'num': 0, 'doubleblah': 0, 'blah': 0}, 
 {'num': 1, 'doubleblah': 0, 'blah': 0}, 
 {'num': 2, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}
]

但实际上它会返回 -

[
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}
]

...当我在函数中添加一些print语句时,我发现它似乎是将数字添加到列表中的每个字典,而不仅仅是当前字典。我真的不知道代码会如何添加到所有dict中,因为我明确地使用x[i] = i将数字添加到当前字典中。

3 个答案:

答案 0 :(得分:8)

正在发生的事情是,您每次都会将相同字典的引用附加到列表中。

print list(map(id, initiate(4)))
# [42283920, 42283920, 42283920, 42283920]

您的功能正确写为:

def initiate(n):
    return [ {'num': i, 'blah': 0, 'doubleblah': 0} for i in range(n) ]

每次都会生成一个新的字典实例。

答案 1 :(得分:0)

使用用户主题,这里有一个解决方案。

但值得注意的是 dict.copy 是一个浅拷贝,这意味着如果源记录中有非原始成员,您的原始问题将持续存在。 更准确地说,问题源于成员是可变数据类型。 整数、字符串、浮点数、布尔值和其他一些内置类型是不可变的。 不变性是一种属性,这意味着对象一旦创建就无法更改。 例如,字典和列表是可变的

def initiate(n, records):
    x = []
    for i in range(n):
        x.append (records.copy())
        x[i]['num'] = i
    return x
    
records = {'num':0,'blah':0,'doubleblah':0}
x = initiate(4, records)

print(x) 
[{'num': 0, 'blah': 0, 'doubleblah': 0}, {'num': 1, 'blah': 0, 'doubleblah': 0}, {'num': 2, 'blah': 0, 'doubleblah': 0}, {'num': 3, 'blah': 0, 'doubleblah': 0}]
[Program finished]

答案 2 :(得分:0)

试试这个:

def initiate(n):
    my_list = []
    for i in range(n):
        my_list.append(
            {
                'num': i,
                'blah': 0,
                'doubleblah': 0
            }
        )
    
    return my_list