我想将两个词典融入一个新的词典。
x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}
z = merge(x, y)
>>> z
{'a': 1, 'b': 3, 'c': 4}
每当两个字典中都有一个关键 k 时,只应保留 y(k) 的值。
我想将两个词典融入一个新的词典。
x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}
z = merge(x, y)
>>> z
{'a': 1, 'b': 3, 'c': 4}
每当两个字典中都有一个关键 k 时,只应保留 y(k) 的值。
当前回答
我将所提出的与 perfplot 比较,并发现
x | y # Python 3.9+
是最快的解决方案,与旧的好解决方案
{**x, **y}
和
temp = x.copy()
temp.update(y)
此分類上一篇
重复字符的代码:
from collections import ChainMap
from itertools import chain
import perfplot
def setup(n):
x = dict(zip(range(n), range(n)))
y = dict(zip(range(n, 2 * n), range(n, 2 * n)))
return x, y
def copy_update(x, y):
temp = x.copy()
temp.update(y)
return temp
def add_items(x, y):
return dict(list(x.items()) + list(y.items()))
def curly_star(x, y):
return {**x, **y}
def chain_map(x, y):
return dict(ChainMap({}, y, x))
def itertools_chain(x, y):
return dict(chain(x.items(), y.items()))
def python39_concat(x, y):
return x | y
b = perfplot.bench(
setup=setup,
kernels=[
copy_update,
add_items,
curly_star,
chain_map,
itertools_chain,
python39_concat,
],
labels=[
"copy_update",
"dict(list(x.items()) + list(y.items()))",
"{**x, **y}",
"chain_map",
"itertools.chain",
"x | y",
],
n_range=[2 ** k for k in range(18)],
xlabel="len(x), len(y)",
equality_check=None,
)
b.save("out.png")
b.show()
其他回答
一种替代:
z = x.copy()
z.update(y)
一个方法是深合的. 使用操作员在 3.9+ 用于使用案例的 dict 新是默认设置的组合,而 dict 现有是使用的现有设置的组合. 我的目标是融入任何添加设置从新没有过写现有设置在现有. 我相信这个重复的实施将允许一个升级一个 dict 与新的值从另一个 dict。
def merge_dict_recursive(new: dict, existing: dict):
merged = new | existing
for k, v in merged.items():
if isinstance(v, dict):
if k not in existing:
# The key is not in existing dict at all, so add entire value
existing[k] = new[k]
merged[k] = merge_dict_recursive(new[k], existing[k])
return merged
示例测试数据:
new
{'dashboard': True,
'depth': {'a': 1, 'b': 22222, 'c': {'d': {'e': 69}}},
'intro': 'this is the dashboard',
'newkey': False,
'show_closed_sessions': False,
'version': None,
'visible_sessions_limit': 9999}
existing
{'dashboard': True,
'depth': {'a': 5},
'intro': 'this is the dashboard',
'newkey': True,
'show_closed_sessions': False,
'version': '2021-08-22 12:00:30.531038+00:00'}
merged
{'dashboard': True,
'depth': {'a': 5, 'b': 22222, 'c': {'d': {'e': 69}}},
'intro': 'this is the dashboard',
'newkey': True,
'show_closed_sessions': False,
'version': '2021-08-22 12:00:30.531038+00:00',
'visible_sessions_limit': 9999}
重复 / 深度更新 a dict
def deepupdate(original, update):
"""
Recursively update a dict.
Subdict's won't be overwritten but also updated.
"""
for key, value in original.iteritems():
if key not in update:
update[key] = value
elif isinstance(value, dict):
deepupdate(value, update[key])
return update
示威:
pluto_original = {
'name': 'Pluto',
'details': {
'tail': True,
'color': 'orange'
}
}
pluto_update = {
'name': 'Pluutoo',
'details': {
'color': 'blue'
}
}
print deepupdate(pluto_original, pluto_update)
结果:
{
'name': 'Pluutoo',
'details': {
'color': 'blue',
'tail': True
}
}
谢谢Radnaw的编辑。
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items() + y.items())
print z
对于两个字典中的关键物品(“b”),您可以通过将最后一个放在输出中来控制哪个。
z1 = dict(x.items() + y.items())
z2 = dict(x, **y)
在我的机器上,至少(一个相当常见的x86_64运行Python 2.5.2),替代Z2不仅更短,更简单,而且更快。
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z1=dict(x.items() + y.items())'
100000 loops, best of 3: 5.67 usec per loop
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z2=dict(x, **y)'
100000 loops, best of 3: 1.53 usec per loop
示例2:不超越的字典,将252条短线地图到整条,反之亦然:
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z1=dict(x.items() + y.items())'
1000 loops, best of 3: 260 usec per loop
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z2=dict(x, **y)'
10000 loops, best of 3: 26.9 usec per loop
z2赢得了大约10的因素,这在我的书中是一个相当大的胜利!
在比较这两个之后,我想知道 z1 的不良性能是否可以归功于构建两个项目列表的顶端,这反过来导致我想知道这个变量是否会更好地工作:
from itertools import chain
z3 = dict(chain(x.iteritems(), y.iteritems()))
% python -m timeit -s 'from itertools import chain; from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z3=dict(chain(x.iteritems(), y.iteritems()))'
10000 loops, best of 3: 66 usec per loop
z0 = dict(x)
z0.update(y)
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z0=dict(x); z0.update(y)'
10000 loops, best of 3: 26.9 usec per loop
你也可以这样写作
z0 = x.copy()
z0.update(y)
正如托尼所做的那样,但(不令人惊讶)评分的差异显然没有对性能的测量效应。 使用任何人看起来对你是正确的。