3

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

这是代表我的问题的代码示例:

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 循环中?

4

2 回答 2

5

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

for i in self.records:
    dic = { 'key1': i[0], 'key2': i[1], 'key3': i[2] }
    parsed.append(dic)
于 2012-10-05T19:50:09.873 回答
5

因为你dic是在循环之外创建的,所以你只创建一个字典。如果你想要三个不同的字典,你需要创建三个不同的字典,所以将初始创建移到dic循环内部。

要回答您更新的问题,问题是尽管您认为您正在为 each 附加一个新的 dict parsed.append(dic),但您只是将相同的 dict 附加了三次。 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,因此您所做的任何更改都会覆盖您之前所做的任何更改。最后,您的列表仅包含字典的最后一个版本,因为所有早期更改都被列表中的所有字典覆盖。

于 2012-10-05T19:50:45.977 回答