在for循环中填充python字典会返回相同的值

Ale*_*Kir 3 python python-2.7

为了项目的需要,我迭代一些数据并将所需的值添加到预制字典中.

这里是条带化的代码示例,代表我的问题:

class Parser:
    def __init__(self):
        self.records = [['value1','value2','value3'], 
                        ['value4','value5','value6'],
                        ['value7','value8','value9']]
    def get_parsed(self):
        parsed = []
        dic = {'key1': '',
               'key2': '',
               'key3': '',
               }
        for i in self.records:
            dic['key1'] = i[0]
            dic['key2'] = i[1]
            dic['key3'] = i[2]
            parsed.append(dic)
        return parsed
Run Code Online (Sandbox Code Playgroud)

我期望得到的是像这样的词典列表:

[{'key1':'value1','key2':'value2','key3':'value3'},
 {'key1':'value4','key2':'value5','key3':'value6'},
 {'key1':'value7','key2':'value8','key3':'value9'}]
Run Code Online (Sandbox Code Playgroud)

但是我得到的是:

[{'key1':'value1','key2':'value2','key3':'value3'},
 {'key1':'value1','key2':'value2','key3':'value3'},
 {'key1':'value1','key2':'value2','key3':'value3'}]
Run Code Online (Sandbox Code Playgroud)

虽然如果我将字典初始化移动到'for'循环 - 我得到了所需的结果,但我不明白为什么会发生这种情况?

编辑:问题是更多"为什么会这样发生"我在ipython中做了一些测试,这就是我所拥有的:

In [1]: d = {'a':'','b':'','c':''}

In [2]: d
Out[2]: {'a': '', 'b': '', 'c': ''}

In [3]: d['a'] = 'value'

In [4]: d['b'] = 'other_value'

In [5]: d['c'] = 'third_value'

In [6]: d
Out[6]: {'a': 'value', 'b': 'other_value', 'c': 'third_value'}

In [7]: d['a'] = 'inserting new value'

In [8]: d
Out[8]: {'a': 'inserting new value', 'b': 'other_value', 'c': 'third_value'}
Run Code Online (Sandbox Code Playgroud)

因此密钥的值可以更新并且它会发生变化,为什么不在FOR循环中发生?

Mar*_*ers 5

您正在修改并将相同的字典插入列表三次.为循环的每次迭代创建一个新字典:

for i in self.records:
    dic = { 'key1': i[0], 'key2': i[1], 'key3': i[2] }
    parsed.append(dic)
Run Code Online (Sandbox Code Playgroud)


Bre*_*arn 5

因为您dic是在循环外创建的,所以只创建一个dict.如果你想要三个不同的dicts,你需要创建三个不同的dicts,所以移动dic循环内的初始创建.

要回答您更新的问题,问题在于,虽然您认为每个都附加一个新的dict parsed.append(dic),但您只需要添加相同的dict三次. Append不复制字典.因此,无论何时修改该dict,所有的dicts都会parse显示更改,因为它们都是相同的dict.此版本的第二个代码示例可能更具说明性:

>>> d = {'a': '', 'b': '', 'c': ''}
>>> stuff = []
>>> stuff.append(d)
>>> print stuff
[{'a': '', 'c': '', 'b': ''}]
>>> d['a'] = 'other'
>>> print stuff
[{'a': 'other', 'c': '', 'b': ''}]
>>> stuff.append(d)
>>> print stuff
[{'a': 'other', 'c': '', 'b': ''}, {'a': 'other', 'c': '', 'b': ''}]
>>> d['a'] = 'yet another'
>>> print stuff
[{'a': 'yet another', 'c': '', 'b': ''}, {'a': 'yet another', 'c': '', 'b': ''}]
Run Code Online (Sandbox Code Playgroud)

请注意,更改dict"有效",因为它确实更改了值,但无论如何,列表仍然多次包含相同的dict,因此您所做的任何更改都会覆盖您之前所做的任何更改.最后,您的列表仅包含dict的最后一个版本,因为所有先前的更改都被覆盖在列表中的所有dicts中.