如果不存在,Python将更新dict中的键

问题:如果不存在,Python将更新dict中的键

如果键不在dict.keys()中,我想将一个键值对插入dict中。基本上我可以做到:

if key not in d.keys():
    d[key] = value

但是有更好的方法吗?或针对此问题的pythonic解决方案是什么?

I want to insert a key-value pair into dict if key not in dict.keys(). Basically I could do it with:

if key not in d.keys():
    d[key] = value

But is there a better way? Or what’s the pythonic solution to this problem?


回答 0

您无需调用d.keys(),因此

if key not in d:
    d[key] = value

足够的。没有更清晰,更易读的方法。

您可以使用再次更新dict.get(),如果键已经存在,它将返回一个现有值:

d[key] = d.get(key, value)

但我强烈建议您反对;这是代码打高尔夫球,妨碍了维护和可读性。

You do not need to call d.keys(), so

if key not in d:
    d[key] = value

is enough. There is no clearer, more readable method.

You could update again with dict.get(), which would return an existing value if the key is already present:

d[key] = d.get(key, value)

but I strongly recommend against this; this is code golfing, hindering maintenance and readability.


回答 1

用途dict.setdefault()

>>> d = {1: 'one'}
>>> d.setdefault(1, '1')
'one'
>>> d    # d has not changed because the key already existed
{1: 'one'}
>>> d.setdefault(2, 'two')
'two'
>>> d
{1: 'one', 2: 'two'}

Use dict.setdefault():

>>> d = {1: 'one'}
>>> d.setdefault(1, '1')
'one'
>>> d    # d has not changed because the key already existed
{1: 'one'}
>>> d.setdefault(2, 'two')
'two'
>>> d
{1: 'one', 2: 'two'}

回答 2

Python 3.9开始,您可以使用merge运算 |符合并两个字典。右侧的dict优先:

new_dict = old_dict | { key: val }

例如:

new_dict = { 'a': 1, 'b': 2 } | { 'b': 42 }

print(new_dict} # {'a': 1, 'b': 42}

注意:这将创建具有更新值的新字典。

Since Python 3.9 you can use the merge operator | to merge two dictionaries. The dict on the right takes precedence:

d = { key: value } | d

Note: this creates a new dictionary with the updated values.


回答 3

使用以下代码,您可以插入多个值,也可以使用默认值,但是您正在创建一个新字典。

d = {**{ key: value }, **default_values}

我已经用投票率最高的答案对其进行了测试,平均而言,这样做的速度更快,如下面的示例所示。

速度测试将基于for循环的方法与带有unpack运算符方法的dict理解进行比较。

如果d = default_vals.copy()在第一种情况下没有复制(),则一旦我们达到10**5或更大的数量级,投票最多的答案就会更快。两种方法的内存占用相同。

With the following you can insert multiple values and also have default values but you’re creating a new dictionary.

d = {**{ key: value }, **default_values}

I’ve tested it with the most voted answer and on average this is faster as it can be seen in the following example, .

Speed test comparing a for loop based method with a dict comprehension with unpack operator method.

if no copy (d = default_vals.copy()) is made on the first case then the most voted answer would be faster once we reach orders of magnitude of 10**5 and greater. Memory footprint of both methods are the same.


回答 4

根据以上答案,setdefault()方法为我工作。

old_attr_name = mydict.setdefault(key, attr_name)
if attr_name != old_attr_name:
    raise RuntimeError(f"Key '{key}' duplication: "
                       f"'{old_attr_name}' and '{attr_name}'.")

虽然此解决方案不是通用的。在这种情况下才适合我。确切的解决方案是检查第key一个(如已经建议的),但是setdefault()我们避免在字典上进行额外的查找,即虽然很小,但仍然可以提高性能。

According to the above answers setdefault() method worked for me.

old_attr_name = mydict.setdefault(key, attr_name)
if attr_name != old_attr_name:
    raise RuntimeError(f"Key '{key}' duplication: "
                       f"'{old_attr_name}' and '{attr_name}'.")

Though this solution is not generic. Just suited me in this certain case. The exact solution would be checking for the key first (as was already advised), but with setdefault() we avoid one extra lookup on the dictionary, that is, though small, but still a performance gain.