我正在尝试附加到埋藏在深层嵌套字典中的列表。但是,每当我尝试附加到列表时,它都会使字典变平:
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'}]}}}}}}}
最佳答案
我认为您可能误解了复制的工作原理。由于 python 具有可变性,因此实现复制的目的是为了避免更改原始值。
复制旨在将对象/值复制为新对象,因此您可以对新对象进行操作,而不更改原始对象。通过创建列表的副本,您将永远无法按预期追加到原始列表。
而是遍历你的字典到列表,并且因为列表是一个可变对象,所以直接更改它。该更改将反射(reflect)在词典中。
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'}]}}}}}}}
至于你的程序失败的原因,只要看看你采取的步骤:
- k 变为
and
,v 变为{'another': {'string': {'separated': {'by': {'underscore': {'my_l': [ ]}}}}}}
- tmp 将 v 复制到一个新对象中(对 tmp 所做的所有更改都不会反射(reflect)在 v 上)
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': []} []
您附加到最后一个值,它是您要更改的实际列表的副本。因此实际列表不会改变,只有 tmp 会改变。 tmp 变为
[{'this': 'that'}]
你说
deeply_nested[k] = copy.deepcopy(tmp)
。从步骤 1.k=any
开始。从步骤 4 开始,tmp=[{'this': 'that'}]
,因此:{'and': [{'this': 'that'}]}
冲洗并重复 10 次即可得到所需的效果。
关于python - 如何附加到深度嵌套在字典中的列表并保留嵌套结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30154358/