我只是在我想做的地方写了一些代码:
def foo(container)
return any((some_obj.attr <= 0 for some_obj in container))
foo
将返回第一个 some_obj
,其中 some_obj.attr
为零或更小。我想,另一种选择是
def foo(container):
return next((some_obj for some_obj in container if some_obj.attr <= 0), False)
但这感觉很老套。
我最终把它写了出来,但我不喜欢它的嵌套有多深。
def foo(container):
for some_obj in container:
if some_obj.attr <= 0:
return some_obj
return False
澄清一下:container
在这种情况下可能不超过 6 个对象(通常是 2 个对象),尽管一般情况更有用。我也在尝试优化以方便阅读,而不是为了性能。
还有比这更好的结构吗?
最佳答案
any
的文档解释它等同于:
def any(iterable):
for element in iterable:
if element:
return True
return False
因此,如果您的代码与用于说明 any
本身的功能的代码具有完全相同的结构,我认为您的代码不会嵌套太深。
不过,我可能会将其包装在一个函数中:
def first(iterable, predicate):
for element in iterable:
if predicate(element):
return element
return False
现在你可以这样做了:
def foo(container):
return first(container, lambda obj: obj.attr <= 0)
或者,也可以只使用生成器表达式,并将其传递给双参数 next
,正如您已经在做的那样:
def foo(container):
return next((obj for obj in container if obj.attr <= 0), False)
具有相同的“深度”,只是水平而不是垂直。
或者,也许,拉出 genexpr 并命名它:
def foo(container):
nonpositives = (obj for obj in container if obj.attr <= 0)
return next(nonpositives, False)
你会如何选择它们?我认为如果谓词太复杂而无法作为 lambda
阅读,但又不够复杂以至于不值得抽象为一个外联函数,我会选择 genexpr。否则,包装函数。但这确实是一个品味问题。
关于python - 返回最后评估的对象的 `any` 的替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30364222/