for循环中的dict()-不同的行为

时间:2018-10-04 11:51:59

标签: python json dictionary for-loop

我正在尝试通过for循环动态更新dict()键的值。

def update_dict():
    f = []
    for i, j in enumerate(list_range):
        test_dict.update({'a': i})
        j['c'] = test_dict
        print(j)
        f.append(j)
    print(f)

test_dict = dict({'a': 1})
list_range = [{'b': i} for i in range(0, 5)]
update_dict()

即使print(j)给出了迭代值(0,1,2,3,4),以某种方式最后一个字典也被整个列表覆盖,并给出错误的输出(4,4,4,4,4)

预期输出

[{'b': 0, 'c': {'a': 0}}, {'b': 1, 'c': {'a': 1}}, {'b': 2, 'c': {'a': 2}}, {'b': 3, 'c': {'a': 3}}, {'b': 4, 'c': {'a': 4}}]

获得输出,

[{'b': 0, 'c': {'a': 4}}, {'b': 1, 'c': {'a': 4}}, {'b': 2, 'c': {'a': 4}}, {'b': 3, 'c': {'a': 4}}, {'b': 4, 'c': {'a': 4}}]

我需要了解字典是如何被覆盖的,避免这种情况的最佳解决方案是什么?

谢谢!

P.S。 :请避免建议列表或字典理解方法作为裸露的答案,因为我知道它们,而这个问题的唯一目的是了解dict()的错误行为。

4 个答案:

答案 0 :(得分:2)

您每次尝试在循环中将值添加到同一词典中,并且随着循环的进行,您将不断替换这些值。

您需要在每次迭代中定义字典,以创建字典的单独引用:

def update_dict():
    f = []
    for i, j in enumerate(list_range):
        test_dict = {'a': i}
        j['c'] = test_dict
        f.append(j)
    print(f)


list_range = [{'b': i} for i in range(0, 5)]
update_dict()

# [{'b': 0, 'c': {'a': 0}}, 
#  {'b': 1, 'c': {'a': 1}},
#  {'b': 2, 'c': {'a': 2}},
#  {'b': 3, 'c': {'a': 3}},
#  {'b': 4, 'c': {'a': 4}}]

答案 1 :(得分:2)

这种行为的原因是列表中的所有引用都指向同一个字典。第j['c'] = test_dict行不会创建字典的副本,而只是使j ['c']引用test_dict。为了获得预期的结果,您需要将此行更改为: j['c'] = test_dict.copy()。它将复制test_dict的深层副本并将其分配给j ['c']。

答案 2 :(得分:1)

@Override
    public void onBackPressed() {
         // Leave empty if you want nothing to happen, or do something else if you wish

    }

答案 3 :(得分:1)

一个更简单的解决方案是遍历list_range并使用c中的值创建b

lista = [{'b': i } for i in range(0, 5)]
for i in lista:
    i['c'] = {'a': i['b']}
# [{'b': 0, 'c': {'a': 0}}, {'b': 1, 'c': {'a': 1}}, {'b': 2, 'c': {'a': 2}}, {'b': 3, 'c': {'a': 3}}, {'b': 4, 'c': {'a': 4}}]