【问题标题】:python get key for dict evaluates defulat part even when the key exists即使密钥存在,python get key for dict也会评估默认部分
【发布时间】:2021-12-08 13:22:29
【问题描述】:

我对@9​​87654321@ 的理解是,如果密钥存在,则不会对默认参数进行评估。还有几个sources 含蓄地留下了这种解释。但事实证明并非如此。

假设有一个 dict 具有 str 或 int 类型的整数键。 因此,检索值模块键类型的一行是使用.get,默认值取决于替代类型的键。

>>> d = {'2':4} 
>>> d.get(2, d['2'])
4
>>> d.get('2', d[2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 2

如果键存在,评估默认参数的意义何在? 这只是方法的糟糕设计还是我过度概括了.get() 的预期功能?

【问题讨论】:

  • d[2] 在传递给函数之前得到评估。
  • 由于 d[2] 不存在,所以抛出错误。需要将有效的默认值传递给 dict.get。

标签: python dictionary keyerror


【解决方案1】:

在这种情况下的主要区别在于,表达式 d[2] 必须在作为参数传递给 get 函数之前进行计算。

发生异常是因为您在此表达式中引用了一个不存在的整数键 2,然后再检查该字典中是否存在 d['2'] 键。

请找到参考:Expressions 6.3.4. Calls

主对象必须评估为可调用对象(用户定义的函数、内置函数……以及所有具有 __call__() 方法的对象都是可调用的)。 在尝试调用之前评估所有参数表达式。

【讨论】:

    【解决方案2】:

    Python 不是一种惰性语言,因此函数的所有参数都在调用函数之前进行评估。这意味着,在您的第二个示例中,d[2] 将在调用d.get 之前进行评估。有些语言(如 Haskell)会接受此代码,因为参数仅在需要时进行评估。

    【讨论】:

    【解决方案3】:

    参数总是被评估,我不知道有任何主流过程语言允许声明函数,以便对参数的评估推迟到以某种方式显式解决。

    如何推迟评估:

    d = { '2': 4 }
    x = d.get('3', lambda: d[2])
    print(x() if callable(x) else x)
    

    .. 但这是一个非常愚蠢的例子。

    编辑:推迟评估的另一种(危险)方式:

    x = d.get('2', False) or d[2]
    

    .. 假设 dict 没有有效结果评估为 False(如 0None)。这是一个很好的射击自己的方法。

    【讨论】:

    • 这是一种有趣的延迟评估方式。如果没有 if 子句,它会更整洁。
    • @FiboKowalsky 为您添加了另一种享受方式。
    • @Jukka_Vaisanen,酷!我不知道逻辑运算符如何使用,例如数字。我以为3 or 5 计算结果为 True,但结果是 3。docs.python.org/3/reference/expressions.html#or
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    相关资源
    最近更新 更多