如何附加到深深嵌套在dict中的列表并保留嵌套结构?

时间:2015-05-10 17:21:18

标签: python list python-2.7 dictionary

我试图追加埋藏在深层嵌套字典中的列表。但是,每当我尝试附加到列表时,它都会使字典变平:

import copy

my_d = {'this': 'that'}
deeply_nested = {'and': {'another': {'string': {'separated': {'by': {'underscore': {'my_l': []}}}}}}}
print 'initial: ', deeply_nested

for i in range(10):
    for k, v in deeply_nested.iteritems():
        tmp = copy.deepcopy(v)
        while not isinstance(tmp, list):
            for v in tmp.values():
                 tmp = copy.deepcopy(v)
        tmp.append(my_d)
        deeply_nested[k] = copy.deepcopy(tmp)

print 'final: ', deeply_nested

结果:

initial:  {'and': {'another': {'string': {'separated': {'by': {'underscore': {'my_l': []}}}}}}}
final:  {'and': [{'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}]}

最终版本缺少嵌套键,应该是:

{'and': {'another': {'string': {'separated': {'by': {'underscore': {'my_l': [{'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}]}}}}}}}

1 个答案:

答案 0 :(得分:2)

我想你可能误解了副本是如何工作的。因为python具有可变性,所以实现了复制,并且确实希望避免更改原始值。

复制旨在将对象/值复制为新对象,因此您可以对新对象执行操作,更改原始对象。通过创建列表副本,您将永远无法按预期附加到原始列表。

而是将您的字典遍历到列表中,并且因为list是一个可变对象,所以直接更改它。这一变化将反映在字典中。

import copy

my_d = {'this': 'that'}
deeply_nested = {'and': {'another': {'string': {'separated': {'by': {'underscore': {'my_l': []}}}}}}}
print 'initial: ', deeply_nested

for i in range(10):
    tmp = deeply_nested.values()[0]
    while not isinstance(tmp,list):
        tmp = tmp.values()[0] #this will reference the list in the dict, changes to tmp are changes to that list.
    tmp.append(my_d)

print 'final: ', deeply_nested

结果是

initial:  {'and': {'another': {'string': {'separated': {'by': {'underscore': {'my_l': []}}}}}}}

final:  {'and': {'another': {'string': {'separated': {'by': {'underscore': {'my_l': [{'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}, {'this': 'that'}]}}}}}}}

至于你的程序失败的原因,只需看看你采取的步骤:

  1. k变为and,v变为{'another': {'string': {'separated': {'by': {'underscore': {'my_l': []}}}}}}
  2. tmp将v复制到一个新对象(对tmp所做的所有更改都不会反映在v上)
  3. tmp遍历剩下的字典:

    {'another': {'string': {'separated': {'by': {'underscore': {'my_l': []}}}}}}
    {'string': {'separated': {'by': {'underscore': {'my_l': []}}}}}
    {'separated': {'by': {'underscore': {'my_l': []}}}}
    {'by': {'underscore': {'my_l': []}}}
    {'underscore': {'my_l': []}}
    {'my_l': []}
    []
    
  4. 您追加到最后一个值,该值是您要更改的实际列表的副本。因此实际列表不会改变,只有tmp。 tmp变为[{'this': 'that'}]

  5. 你说deeply_nested[k] = copy.deepcopy(tmp)。从第1步开始.k = any。从步骤4. tmp = [{'this': 'that'}],因此:

    {'and': [{'this': 'that'}]}
    

    冲洗并重复10次以获得所需物品。