奇怪的额外循环

Zam*_*tta 5 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)
Run Code Online (Sandbox Code Playgroud)

我希望函数能够返回 -

[
 {'num': 0, 'doubleblah': 0, 'blah': 0}, 
 {'num': 1, 'doubleblah': 0, 'blah': 0}, 
 {'num': 2, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}
]
Run Code Online (Sandbox Code Playgroud)

但它实际上归还了这个 -

[
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}
]
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*nts 8

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

print list(map(id, initiate(4)))
# [42283920, 42283920, 42283920, 42283920]
Run Code Online (Sandbox Code Playgroud)

您的功能正确写为:

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

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

  • 或者,OP可以附加`records.copy()`而不是附加`records` - 你的方式可能更惯用,但提到`copy`可能会使代码中的实际出错更明显一些. (4认同)