复制复杂的字典结构
问题描述:
假设你有字典的字典,但你想复制几乎整个结构(除了最内层的字典的值)。下面的代码可以做我想做的,但我肯定有一个更聪明的方式来做到这一点:复制复杂的字典结构
import sys
def main(argv=()):
# original dictionary
data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}}
# new values for the innermost keys
newd = {'l1' : 1, 'l2' : 2, 't1' : 3, 't2' : 4}
copy = dict.fromkeys(data.keys(), {})
for k in copy.keys():
copy[k] = dict.fromkeys(data[k].keys(), None)
for k in copy.values():
for e in k.keys():
k[e] = newd[e]
print(data)
print(copy)
if __name__ == "__main__":
sys.exit(main())
所以上面打印的代码:
{1: {'l2': [2, 1, 6], 'l1': [1, 2, 3]}, 2: {'t1': ('w?', 2), 't2': ('h!', 4)}}
{1: {'l2': 2, 'l1': 1}, 2: {'t1': 3, 't2': 4}}
,这是结果我想到,但上面的代码似乎太冗长了。有一点需要注意的是,在实际的例子中,最里面的键的值并不那么简单,但它们是numpy数组,所以我不想对整个结构进行深层拷贝,然后替换这些值。
答
您可以使用(从代码中假设的Python 3):
>>> copy = {outer_key: {inner_key: newd.get(inner_key, inner_dict[inner_key]) for inner_key in inner_dict} for outer_key,inner_dict in data.items()}
>>> copy
{1: {'l1': 1, 'l2': 2}, 2: {'t1': 3, 't2': 4}}
>>> data
{1: {'l1': [1, 2, 3], 'l2': [2, 1, 6]}, 2: {'t1': ('w?', 2), 't2': ('h!', 4)}}
可以简化newd.get(inner_key, inner_dict[inner_key])
到newd[inner_key]
,如果你是100%肯定,每一个按键都在newd
。或者如果您不关心丢失不在newd
中的值的问题,则返回newd.get(inner_key)
。
答
使用复印功能模块:
import copy
data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}}
cdata = copy.deepcopy(data)
那么你就必须修改最后类型的字典与新值的副本。
查看复印模块进行深浅复印。
如果你打算用手来避免填充最后一层,那么递归就是这样做的方法。
了解复制模块至少如何执行它,并使用dict.copy()方法而不是使用fromkeys()构造新的字典。
使用循环来做到这一点,限制你确切数量的内置词典。 如果你的字典有固定的形状,然后使用循环。
答
使用自己的代码,你不需要任何地方调用.keys,您可以在第一个循环创建类型的字典:
def main():
# original dictionary
data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}}
# new values for the innermost keys
newd = {'l1' : 1, 'l2' : 2, 't1' : 3, 't2' : 4}
copy = dict.fromkeys(data, {})
for k in copy:
copy[k] = {key:newd[key] for key in data[k]}
请阅读我的深度复制最后的意见。 – aaragon
对不起,有关numpy数组滑落的内容。但是,我仍然告诉你该怎么做。去看看复制模块是如何做的,然后写出类似的算法,它会考虑你的规格。这是我的答案的精髓。另外,复制模块非常灵活,您可以控制一些正在进行的复制,特别是在使用自己的对象时。 – Dalen