Python:`如果键入dict`与`try/except` - 这是更具可读性的成语?

Lee*_*ile 86 python idioms readability code-readability defaultdict

我有一个关于习语和可读性的问题,似乎有一个针对这个特殊情况的Python哲学冲突:

我想从字典B中构建字典A.如果B中不存在特定的键,则不执行任何操作并继续.

哪种方式更好?

try:
    A["blah"] = B["blah"]
except KeyError:
    pass
Run Code Online (Sandbox Code Playgroud)

要么

if "blah" in B:
    A["blah"] = B["blah"]
Run Code Online (Sandbox Code Playgroud)

"做并请求原谅"与"简单和明确".

哪个更好?为什么?

Gle*_*ard 69

例外不是条件限制.

条件版本更清晰.这是很自然的:这是简单的流量控制,这是条件的设计,而不是例外.

在循环中执行这些查找时,异常版本主要用作优化:对于某些算法,它允许从内部循环中消除测试.它没有这个好处.它有一个小优势,它避免了说"blah"两次,但如果你做了很多这些,你应该有一个辅助move_key功能.

一般来说,我强烈建议默认情况下坚持使用条件版本,除非您有特殊原因不这样做.条件是显而易见的方法,这通常是一个强烈的建议,更喜欢一种解决方案而不是另一种解决方案.

  • 除了Python之外,这个答案对于我所知道的任何语言都是正确的. (7认同)
  • 而且,特别是在Python中,EAFP被广泛使用. (5认同)
  • 我不同意.如果你说"做X,如果那不行,就做Y".在这里反对条件解决方案的主要原因是,你必须更频繁地写"bla",这会导致更容易出错的情况. (3认同)
  • 如果您像在Python中使用条件一样使用异常,我希望没有人需要阅读它。 (3认同)

lqc*_*lqc 51

还有第三种方法可以避免异常和双重查找,如果查找很昂贵,这可能很重要:

value = B.get("blah", None)
if value is None: 
    A["blah"] = value
Run Code Online (Sandbox Code Playgroud)

如果您希望字典包含None值,您可以使用更多深奥的常量NotImplemented,Ellipsis或者创建一个新的常量:

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

无论如何,使用update()对我来说是最可读的选项:

a.update((k, b[k]) for k in ("foo", "bar", "blah") if k in b)
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案还具有线程安全的优点. (3认同)

pyf*_*unc 14

据我所知,你想用dict B中的键值对更新dict A.

update 是一个更好的选择.

A.update(B)
Run Code Online (Sandbox Code Playgroud)

例:

>>> 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}
>>> 
Run Code Online (Sandbox Code Playgroud)


Sam*_*nen 8

Python性能维基直接引用:

除了第一次,每次看到一个单词时if语句的测试失败.如果要计算大量单词,很多单词可能会出现多次.在一个值的初始化只发生一次并且该值的增加将多次发生的情况下,使用try语句会更便宜.

所以看来两种选择都是可行的,取决于情况.有关详细信息,您可以查看此链接:Try-except-performance