简体   繁体   English

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

[英]Filling a python dictionary in for loop returns same values

For the needs of the project im iterating over some data and adding needed values to premade dictionary. 对于项目的需求,迭代一些数据并向预制词典中添加所需的值。

here is striped down example of code which represents my question: 这是代表我的问题的简化代码示例:

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

What i expect to get is list of dicts like this: 我期望得到的是这样的字典列表:

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

But what im getting is: 但是我得到的是:

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

Though if i move dictionary initialization into 'for' loop - im getting the desired result but i don't understand why is that happening? 虽然如果我将字典初始化移动到“ for”循环中,则无法获得所需的结果,但是我不明白为什么会这样?

EDIT: The question is more "Why does it happens this way" I did some testing in ipython and that's what i've got: 编辑:问题更多是“为什么会这样发生”,我在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'}

So the value of the key could be updated and it changes , why doesn't it happen in FOR loop? 因此,密钥的值可以更新并且可以更改 ,为什么它不在FOR循环中发生?

You are modifying and inserting the same dictionary to your list three times. 您正在修改同一个字典并将其插入到列表中三次。 Create a new dictionary for each iteration of the loop: 为循环的每次迭代创建一个新的字典

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

Because your dic is created outside the loop, you only create one dict. 由于您的dic是在循环外部创建的,因此您只能创建一个dict。 If you want three different dicts, you need to create three different dicts, so move the initial creation of dic inside the loop. 如果需要三个不同的字典,则需要创建三个不同的字典,因此请在循环内移动dic的初始创建。

To answer your updated question, the issue is that although you think you are appending a new dict with each parsed.append(dic) , you are just appending the same dict three times. 为了回答您更新的问题,问题在于,尽管您认为要在每个parsed.append(dic)添加一个新字典,但您只是将同一字典添加了三次。 Append doesn't copy the dict. Append不会复制该字典。 So whenever you modify that dict, all the dicts in parse show the change, since they are all the same dict. 因此,每当您修改该字典时, parse所有字典都会显示更改,因为它们都是相同的字典。 This version of your second code example may be more illustrative: 您的第二个代码示例的此版本可能更具说明性:

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

Notice that changing the dict "works" in that it indeed changes the value, but regardless of that, the list still contains the same dict multiple times, so any changes you make overwrite whatever changes you made earlier. 请注意,更改dict“有效”是因为它确实会更改值,但是无论如何,列表仍然多次包含相同的dict,因此您所做的任何更改都会覆盖您之前所做的更改。 In the end, your list only contains the last version of the dict, because all earlier changes were overwritten in all dicts in the list. 最后,您的列表仅包含字典的最新版本,因为列表中的所有字典都覆盖了所有较早的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM