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

时间:2012-10-05 19:48:22

标签: 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

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

[{'key1':'value1','key2':'value2','key3':'value3'},
 {'key1':'value4','key2':'value5','key3':'value6'},
 {'key1':'value7','key2':'value8','key3':'value9'}]

但是我得到的是:

[{'key1':'value1','key2':'value2','key3':'value3'},
 {'key1':'value1','key2':'value2','key3':'value3'},
 {'key1':'value1','key2':'value2','key3':'value3'}]

虽然如果我将字典初始化移动到'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'}

因此密钥的价值可以更新,更改,为什么不在FOR循环中发生?

2 个答案:

答案 0 :(得分:5)

您正在修改相同的词典并将其插入列表三次。为循环的每次迭代创建新词典

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

答案 1 :(得分:5)

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

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

>>> 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': ''}]

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