在Python lambda表达式中处理len()中的NoneType?

在Python lambda表达式中处理len()中的NoneType?,python,lambda,python-2.4,Python,Lambda,Python 2.4,据我所知,Python lambda只允许表达式,不允许语句。我有一个例子,我在lambda表达式中使用len,并试图获得函数调用返回值的长度。但是,该函数调用有可能返回None,这会破坏len。有没有优雅的方法 例如: def foo(obj_list, field): return maxk(obj_list, key=lambda obj: len(nested_getattr(obj, field))) 在上面的例子中,maxk是max的一个版本,它接受一个键参数。我使用的是P

据我所知,Python lambda只允许表达式,不允许语句。我有一个例子,我在lambda表达式中使用len,并试图获得函数调用返回值的长度。但是,该函数调用有可能返回None,这会破坏len。有没有优雅的方法

例如:

def foo(obj_list, field):
    return maxk(obj_list, key=lambda obj: len(nested_getattr(obj, field)))
在上面的例子中,maxk是max的一个版本,它接受一个键参数。我使用的是Python2.4,目前无法使用更高的版本,因此我有一个max的自定义实现,该实现采用了一个关键参数,来源请参考文章140122和140143。nested_getattr是另一个实用程序函数,其作用类似于getattr,但可以获取嵌套在另一个函数中的属性。这是可以找到的

示例函数所做的是,我在变量/名称更改时使用的实际函数是遍历对象列表obj_list,比较字段中值的长度,并返回列表中字段最大的对象

但是,如果在字段中为每个对象指定的属性返回None,则len将因TypeError而阻塞。我想我可以使用内联条件来解决这个问题,但是我必须调用nested_getattr两次,一次用于检查,如果其返回值不是None,则可能需要调用第二次。我更愿意将其返回值缓存到变量中,并在决定返回什么之前在条件上运行它,或者让生成器表达式完全跳过它


处理这个问题的好方法是什么?我对该函数的其他实现、maxk或嵌套的_getattr(如果需要)持开放态度。

只需将该函数单独定义为常规函数,然后将其传递到maxk:

def getLen(obj):
    val = nested_getattr(obj, field)
    if val is None:
        return 0
    else:
        return len(val)
return maxk(obj, key=getLen)
lambda用于编写内联单表达式函数比编写单独函数更容易的情况。如果想写lambda比写一个普通函数更难,那就写一个普通函数吧。没有必要花时间将其安装到lambda中,因为在这种情况下,lambda不会为您带来任何好处

编辑:lambda是字节码,与执行相同操作的非lambda函数相同

>>> f = lambda x: x**2
>>> def g(x):
...     return x**2
>>> import dis
>>> dis.dis(f)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_POWER        
              7 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_POWER        
              7 RETURN_VALUE     
我现在无法在2.4上进行测试,但这在3.2中有效。

可能是:

lambda val: len(val or [])

您可以将第三个参数添加到嵌套的_getattr,其含义与getattr的第三个参数相同:

同样,在这种特殊情况下,@DSM建议的字段或字段也可以正常工作,如果可能的话,返回值是序列而不是无


一般来说,@BrenBarn建议的命名函数可能更可取。

同意-lambdas通常是一个单独使用的工具,除非它非常简单。Python函数是对象,只需使用def并使其更简单、更清晰。这也可以使用三元运算符来简化:如果val为None-else lenval.+1,则返回0。最初我建议key=lambda obj:lennested_getattrobj,field或[],但这并不是一般性的只适用于0,你关于lambda的观点是很好的。是的,lambda表达式非常简单,工作很好,直到我做了其他更改,必须处理非类型。基本上是想看看我是否能在处理非类型的同时保留lambda的使用。@Kumba清晰度应该总是比速度更重要,除非它是你应用中的瓶颈,而对于三元运算符,它只是短了一点,没什么重要。@Kumba:你错了。lambda与任何其他Python函数没有什么不同。我用一个示例编辑了我的答案,该示例显示了一个示例函数的相同字节码。max不也接受一个键吗?最大值[1,2,3],键=λx:4-x@JoranBeasley:我不认为Python 2.4中没有,这是OP必须使用的。Python 2.4版本中没有。看,我认为@BrenBarn的命名函数是正确的选择,因为它很清晰。len调用通常检查字符串属性的长度,尽管在我的对象中,它也有可能是实现len的另一个对象。如果第三个参数适用于不同的情况,我也可以使用您修改嵌套的_getattr的想法。@Kumba:我已将[]替换为。它不会改变结果,但在代码的上下文中可能更可读。
lambda val: len(val or [])
len(nested_getattr(obj, field, ''))