dict.get(None) 在具有 None 值的 dict 上采用默认 arg

如何解决dict.get(None) 在具有 None 值的 dict 上采用默认 arg?

开发过程中遇到dict.get(None) 在具有 None 值的 dict 上采用默认 arg的问题如何解决?下面主要结合日常开发的经验,给出你关于dict.get(None) 在具有 None 值的 dict 上采用默认 arg的解决方法建议,希望对你解决dict.get(None) 在具有 None 值的 dict 上采用默认 arg有所启发或帮助;

问题描述

我试图概括这种情况:

def func(t):
    # code which doesn't accept None's

def foo(a):
    if a in ('',None):
        return None
    return func(a)

def foo_b(a):
    if a in ('',None):
        return None
    elif a == 'b'
         return 0
    return func(a)

我试图解决它的方法是定义一个字典:

defaults = {None: None,'': None}

def foo(a):
    return defaults.get(a,func(a))

def foo_b(a):
    defaults_b = {'bar': 0,**defaults}
    return defaults_b.get(a,func(a))

运行脚本时:

foo_b(None)

它进入 get 方法, 从 None 字典取回 defaults使用 func() 进入 None 方法 我得到错误原因 func() 方法不排除 None

用python解决这个问题的最佳实践是什么?

解决方法

这行不通,因为函数的所有参数在调用函数之前都已计算。所以当你写

defaults.get(a,func(a))

它首先计算 afunc(a),并将这两个结果传递给 defaults.get()。由于 func(a) 不适用于某些 a 值,因此在进入 defaults.get() 之前您会收到错误消息。

解决这个问题的一般方法是默认为一个函数,只有在必要时才会调用。您需要编写自己的 dict.get() 版本,以这种方式工作。

def dict_get_f(d,key,default_fun):
    if key in d:
        return d[key]
    return default_fun()

然后你可以像这样使用它:

def foo(a):
    return dict_get_f(defaults,a,lambda: func(a))
,

为什么不直接检查函数本身?

def func(t):
    if t is None:
        return None
    # go on with the code

    
,

问题

正如@Barmar 在他们的回答中指出的那样,问题不在于 dict.get 的行为,而是在调用函数之前评估所有参数的事实,因此 defaults.get(a,func(a)) 调用 {{1} } 在使用该值调用 func(a) 之前。

解决方案 1:defaults.get

解决此问题的另一种方法是使用 collections.defaultdict,它提供了一种在值不在字典中时调用函数的方法。

因为你的字典很小,复制它们的成本很低,所以这个解决方案可以做到这一点。

collections.defaultdict

解决方案 2:无处不在的函数!

您可以采用的另一种方法是将 from collections import defaultdict defaults = {None: None,'': None} def func(arg): """Some function that cannot be called with None""" if arg is None: raise ValueError() print(f'func called with {arg}') def foo(a): return defaultdict(lambda: func(a),defaults)[a] def foo_b(a): defaults_b = {'bar': 0,**defaults} return defaultdict(lambda: func(a),defaults_b)[a] if __name__ == '__main__': print(foo(None)) print(foo('')) print(foo(123)) print(foo(123)) print(foo_b(None)) print(foo_b('bar')) 字典设为函数字典,并使用默认值 defaults,以避免使用 lambda: func(a) 调用函数。因此,None 将返回一个返回正确值的函数,然后您可以调用该函数来获取您想要的值:defaults.get(a,lambda: func(a))

完整的程序:

defaults.get(a,lambda: func(a))()

解决方案 3:浮华且有些混淆的布尔运算短路

作为第三种选择,您可以在 python 中使用 defaults = {None: (lambda: None),'': (lambda: None)} def func(arg): """Some function that cannot be called with None""" if arg is None: raise ValueError() print(f'func called with {arg}') def foo(a): return defaults.get(a,lambda: func(a))() def foo_b(a): defaults_b = {'bar': (lambda: 0),**defaults} return defaults_b.get(a,lambda: func(a))() if __name__ == '__main__': print(foo(None)) print(foo('')) print(foo(123)) print(foo(123)) print(foo_b(None)) print(foo_b('bar')) 的行为,根据您列出的所有默认值都是“falsy”(What is Truthy and Falsy? How is it different from True and False?)这一事实进行回复。在python中,and是短路的,这意味着如果a and ba或falsy,那么它已经知道False不能是a and b,所以它返回 True,或者如果 a 为真,则返回 a

因此,如果 ba,则 None 等于 defaults.get(a,True) and func(a)None and func(a) 是假的,所以 None 等于 None and func(a)。如果 None 不在 a 中,则 defaults 等于 defaults.get(a,True) and func(a),它等于 True and func(a),因此函数被调用。

请注意,如果您使用真实的默认值,例如,这将不起作用。 if func(a),对于可维护性来说可能很难理解 - 我只是想我会给出另一个选择。

defaults = {None: None,'': None,'bar': 'something'}

编程问答问答

附加了我的广告链接[https://plnkr.co/edit/lnF09XtK3eDo1a5v] 我们是否可以选择在不同的组值之间放置一个
我已经使用TensorFlow 2.2版本训练了我的Keras模型。现在必须将其部署在CPP中,即希望以c ++语言进行推理/
我们正在使用ag-grid-aurelia组件。尝试使用rowModelType作为客户端加载网格。如果数据超过1万行,则加载将
我正在尝试从表中检索ID,然后将其发布到另一个表中,但我无法获取该值。 这是我的模型发布模型代
在C ++中,使用+进行字符串连接是否不好?例如下面的 <pre><code>string str = &#34;&#34;; int n = 10; for (int i =
<pre><code>&lt;select name=&#34;organization&#34; id=&#34;orgId&#34; style=&#34;&lt;?php echo $_POST[&#39;report_type&#39;] == &#39;org_part
<h2> parent.component.ts </h2> <pre><code>public test(){ //some code..... } </code></pre> <h2> parent.component.html </h2> <pre><code>&lt;a
我有两个数据框。一个数据框包含不同公司的财务数据,另一数据框包含相应的行业代码。我现在想向
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注