5

我对 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}
]

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

4

3 回答 3

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) ]

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

于 2012-10-22T18:05:05.533 回答
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]
于 2021-03-10T07:23:40.040 回答
0

尝试这个:

def initiate(n):
    my_list = []
    for i in range(n):
        my_list.append(
            {
                'num': i,
                'blah': 0,
                'doubleblah': 0
            }
        )
    
    return my_list
于 2021-03-10T07:36:22.163 回答