Python - FOR循环不在嵌套字典中写入正确的值

时间:2016-05-28 10:30:23

标签: python for-loop dictionary nested

希望有人可以帮助我,因为我的研究都没有帮助过我。我有一个简单的字典:

mydict = {
    1: {1: 'Foo'},
    2: {1: 'Bar'}
    }

我正在复制分配新密钥值的每个键/值对:

nextKey = len(mydict) + 1
for currKey in range(len(mydict)):
    mydict[nextKey] = mydict[currKey + 1]
    nextKey += 1

这给了我一个 mydict

{
    1: {1: 'Foo'},
    2: {1: 'Bar'},
    3: {1: 'Foo'},
    4: {1: 'Bar'},
    }

我现在想要为所有现有的嵌套字典添加新的键值对。每个键的键应为'2',每个嵌套字典的值应增加:

newValue = 1
for key in mydict:
    mydict[key][2] = newValue
    newValue += 1

我期待:

{
    1: {1: 'Foo', 2: 1},
    2: {1: 'Bar', 2: 2},
    3: {1: 'Foo', 2: 3},
    4: {1: 'Bar', 2: 4},
    }

但是这给了我一个 mydict

{
    1: {1: 'Foo', 2: 3},
    2: {1: 'Bar', 2: 4},
    3: {1: 'Foo', 2: 3},
    4: {1: 'Bar', 2: 4},
    }

我已经使用了我正在使用的IDE的可视化工具,在我运行循环以复制键/值对之后,新键只引用了重复的值而不是实际包含它,也许这有一些东西用它做什么?

IDE Visualisation

有人可以帮忙解释一下吗?

2 个答案:

答案 0 :(得分:0)

这是因为在你的第一个循环中你没有复制嵌套的词典,而只是添加对同一个词典的新引用。

也许给出一个更清晰的例子:如果你在两个循环(使用原始代码)后突破第二个循环,你的输出将是:

{1: {1: 'Foo', 2: 1}, 
2: {1: 'Bar', 2: 2}, 
3: {1: 'Foo', 2: 1}, 
4: {1: 'Bar', 2: 2}}

所以你可以像这样修复你的第一个循环:

for currKey in range(len(mydict)):
    mydict[nextKey] = mydict[currKey + 1].copy()
    nextKey += 1

copy()函数创建字典的真实副本,以便您可以在第二个循环中访问这4个不同的字典。

答案 1 :(得分:0)

你的假设是对的。最小的例子:

import decorator
import inspect

def f(x, a, b):
    return a+b*x

def fmaker(f,is_complex):
    argspec = inspect.getargspec(f)
    args = argspec.args[:]
    fname = f.func_name

    s1 = "{}_r(".format(fname)
    s2 = "return f("
    for arg, cplx in zip(args, is_complex):
        if not cplx:
            s1 += "{},".format(arg)
            s2 += "{},".format(arg)
        else:
            s1 += "{}_r,".format(arg)
            s1 += "{}_i,".format(arg)
            s2 += "{}_r+1J*{}_i,".format(arg,arg)

    s1 += ')'
    s2 += ')'
    return decorator.FunctionMaker.create(s1,s2,dict(f=f))

is_complex = [False, True, True]
f_r = fmaker(f,is_complex)

# prints ArgSpec(args=['x', 'a_r', 'a_i', 'b_r', 'b_i'], varargs=None, keywords=None, defaults=())
print(inspect.getargspec(f_r)) 
print( f(1,2+3J,4+5J) == f_r(1,2,3,4,5) )

如果要复制对象,有几种方法可以执行此操作:

  • 列表:>>> a = {1: {"a": "A"}, 2:{"b": "B"}} >>> a[3] = a[1] >>> a {1: {'a': 'A'}, 2: {'b': 'B'}, 3: {'a': 'A'}} >>> id(a[3]) # a[1] and a[3] are the same object 140510365203264 >>> id(a[1]) 140510365203264 >>> a[1]['a'] = "changed" # so changing one affects the "oter one" >>> a {1: {'a': 'changed'}, 2: set(['B', 'b']), 3: {'a': 'changed'}} ,使用切片表示法
  • for dictionaries:new = old[:]
  • 另请参阅copy module