在 for 循环中填充 python 字典返回相同的值 [英] Filling a python dictionary in for loop returns same values

查看:87
本文介绍了在 for 循环中填充 python 字典返回相同的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

类解析器:def __init__(self):self.records = [['value1','value2','value3'],['value4','value5','value6'],['value7','value8','value9']]def get_parsed(self):解析 = []dic = {'key1': '','key2': '','key3': '',}因为我在 self.records 中:dic['key1'] = i[0]dic['key2'] = i[1]dic['key3'] = i[2]parsed.append(dic)返回解析

我希望得到的是这样的字典列表:

[{'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 中做了一些测试,这就是我所得到的:

在[1]中:d = {'a':'','b':'','c':''}在 [2] 中:d出[2]:{'a':'','b':'','c':''}在 [3] 中:d['a'] = 'value'在 [4] 中:d['b'] = 'other_value'在 [5] 中:d['c'] = 'third_value'在[6]中:d出[6]:{'a':'值','b':'other_value','c':'third_value'}在 [7] 中:d['a'] = '插入新值'在[8]中:d出[8]:{'a':'插入新值','b':'other_value','c':'third_value'}

所以键的值可以被更新并且它改变,为什么它不会发生在 FOR 循环中?

解决方案

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

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

<预><代码>>>>d = {'a': '', 'b': '', 'c': ''}>>>东西 = []>>>东西.附加(d)>>>打印东西[{'a':'','c':'','b':''}]>>>d['a'] = '其他'>>>打印东西[{'a':'其他','c':'','b':''}]>>>东西.附加(d)>>>打印东西[{'a':'其他','c':'','b':''},{'a':'其他','c':'','b':''}]>>>d['a'] = '又一个'>>>打印东西[{'a':'又一个','c':'','b':''},{'a':'又一个','c':'','b':''}]

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

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?

EDIT: The question is more "Why does it happens this way" I did some testing in ipython and that's what i've got:

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?

解决方案

Because your dic is created outside the loop, you only create one dict. If you want three different dicts, you need to create three different dicts, so move the initial creation of dic inside the loop.

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. Append doesn't copy the dict. So whenever you modify that dict, all the dicts in parse show the change, since they are all the same dict. 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. 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.

这篇关于在 for 循环中填充 python 字典返回相同的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆