复制复杂的字典结构
copy complex dictionary structure
假设你有一个字典的字典,但你想复制几乎整个结构(除了最里面的字典的值)。下面的代码可以做我想做的事,但我相信有更聪明的方法来做到这一点:
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)}}
如果您 100% 确定每个键都在 newd
中,则可以将 newd.get(inner_key, inner_dict[inner_key])
简化为 newd[inner_key]
。或者 newd.get(inner_key)
如果您不在乎但丢失不在 newd
.
中的值
使用复制模块:
import copy
data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}}
cdata = copy.deepcopy(data)
然后您必须用新值修改副本中的最后一个字典。
深拷贝和浅拷贝见拷贝模块。
如果您要手动执行此操作以避免填充最后一层,递归是执行此操作的方法。
至少看看 copy 模块是如何做到的,并使用 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]}
假设你有一个字典的字典,但你想复制几乎整个结构(除了最里面的字典的值)。下面的代码可以做我想做的事,但我相信有更聪明的方法来做到这一点:
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)}}
如果您 100% 确定每个键都在 newd
中,则可以将 newd.get(inner_key, inner_dict[inner_key])
简化为 newd[inner_key]
。或者 newd.get(inner_key)
如果您不在乎但丢失不在 newd
.
使用复制模块:
import copy
data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}}
cdata = copy.deepcopy(data)
然后您必须用新值修改副本中的最后一个字典。
深拷贝和浅拷贝见拷贝模块。
如果您要手动执行此操作以避免填充最后一层,递归是执行此操作的方法。
至少看看 copy 模块是如何做到的,并使用 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]}