`if key in dict` 与 `try/except` - 哪种语法更易读?

114 投票
11 回答
90967 浏览
提问于 2025-04-16 08:55

我有一个关于习惯用法和可读性的问题,在这种情况下,Python的两种理念似乎有些冲突:

我想从字典B构建字典A。如果字典B中没有某个特定的键,就什么都不做,继续进行。

哪种方式更好呢?

try:
    A["blah"] = B["blah"]
except KeyError:
    pass

或者

if "blah" in B:
    A["blah"] = B["blah"]

“做了再求原谅” vs. “简单明了”。

哪种更好,为什么呢?

11 个回答

15

根据我的理解,你想把字典A更新为字典B中的键值对。

使用update会更好。

A.update(B)

举个例子:

>>> A = {'a':1, 'b': 2, 'c':3}
>>> B = {'d': 2, 'b':5, 'c': 4}
>>> A.update(B)
>>> A
{'a': 1, 'c': 4, 'b': 5, 'd': 2}
>>> 
87

还有一种方法可以避免出现异常和重复查找,这在查找过程比较耗费资源时特别重要:

value = B.get("blah", None)
if value is not None: 
    A["blah"] = value

如果你预计字典中可能会有 None 值,你可以使用一些比较冷门的常量,比如 NotImplementedEllipsis,或者自己定义一个新的常量:

MyConst = object()
def update_key(A, B, key):
    value = B.get(key, MyConst)
    if value is not MyConst: 
        A[key] = value

总之,对我来说,使用 update() 是最容易理解的选择:

a.update((k, b[k]) for k in ("foo", "bar", "blah") if k in b)
86

异常处理和条件判断是两回事。

使用条件判断的方式更清晰。这是很自然的,因为条件判断就是用来控制程序流程的,而异常处理并不是为这个目的设计的。

异常处理主要是在循环中进行查找时作为一种优化手段:对于某些算法,它可以让我们在内部循环中省去一些测试。不过在这里并没有这个好处。虽然这样做可以避免重复写"blah",但如果你需要做很多这样的操作,最好还是写一个辅助函数move_key

总的来说,除非你有特别的理由,否则我强烈建议默认使用条件判断。条件判断是最明显的做法,通常这意味着我们应该优先选择这种解决方案。

撰写回答