Python 中的多参数空合并和内置 "or" 函数
Multi-argument null coalesce and built-in "or" function in Python
Python 有一个很好的空合并语法:
c = a or b
如果 a
不是 False
、None
、空或 0
,则将 c
设置为 a
,否则 c
设置为 b
.
(是的,技术上 这不是空合并,它更像是 bool
合并,但对于这个问题的目的来说已经足够接近了。)
对于对象集合,没有明显的方法可以做到这一点,所以我写了一个函数来做到这一点:
from functools import reduce
def or_func(x, y):
return x or y
def null_coalesce(*a):
return reduce(or_func, a)
这行得通,但是我自己写 or_func
似乎不是最理想的 - 肯定有像 __or__
这样的内置程序吧?我尝试使用 object.__or__
and operator.__or__
,但第一个给出 AttributeError
,第二个指的是按位 |
(或)运算符。
因此我有两个问题:
- 有没有像
a or b
一样的内置函数?
- 是否有这样一个空合并函数的内置实现?
两者的答案似乎是否定的,但这让我有些惊讶。
它不完全是一个内置的,但你想要实现的可以很容易地完成:
def null_coalesce(*a):
return next(x for x in a if x)
它很懒,所以它会像a or b or c
一样短路,但不像reduce
。
您还可以通过以下方式使其特定于 null:
def null_coalesce(*a):
return next(x for x in a if x is not None)
Is there a built-in function which I can use which acts like a or b?
没有。引用自 this answer on why:
The or
and and
operators can't be expressed as functions because of their short-circuiting behavior:
False and some_function()
True or some_function()
in these cases, some_function()
is never called.
A hypothetical or_(True, some_function())
, on the other hand, would have to call some_function()
, because function arguments are always evaluated before the function is called.
Is there a built-in implementation of such a null coalesce function?
不,没有。但是,the Python documentation page for itertools
建议如下:
def first_true(iterable, default=False, pred=None):
"""Returns the first true value in the iterable.
If no true value is found, returns *default*
If *pred* is not None, returns the first item
for which pred(item) is true.
"""
# first_true([a,b,c], x) --> a or b or c or x
# first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
return next(filter(pred, iterable), default)
Marco 说得对,没有内置,itertools 有配方。您还可以 pip install boltons
使用 boltons.iterutils.first()
实用程序,如果您想要短路,这是完美的选择。
from boltons.iterutils import first
c = first([a, b])
还有一些其他相关且方便的 reduction tools in iterutils
,例如 one()
。
我已经做了足够多的上述工作,以至于我最终想要一个更高级别的工具,可以在 Python 数据结构,产生 glom
and its Coalesce
功能。
from glom import glom, Coalesce
target = {'b': 1}
spec = Coalesce('a', 'b')
c = glom(target, spec)
# c = 1
(完全公开,如上所述,我维护 glom
和 boltons
,这是个好消息,因为 you can bug me 如果你发现错误。)
Python 有一个很好的空合并语法:
c = a or b
如果 a
不是 False
、None
、空或 0
,则将 c
设置为 a
,否则 c
设置为 b
.
(是的,技术上 这不是空合并,它更像是 bool
合并,但对于这个问题的目的来说已经足够接近了。)
对于对象集合,没有明显的方法可以做到这一点,所以我写了一个函数来做到这一点:
from functools import reduce
def or_func(x, y):
return x or y
def null_coalesce(*a):
return reduce(or_func, a)
这行得通,但是我自己写 or_func
似乎不是最理想的 - 肯定有像 __or__
这样的内置程序吧?我尝试使用 object.__or__
and operator.__or__
,但第一个给出 AttributeError
,第二个指的是按位 |
(或)运算符。
因此我有两个问题:
- 有没有像
a or b
一样的内置函数? - 是否有这样一个空合并函数的内置实现?
两者的答案似乎是否定的,但这让我有些惊讶。
它不完全是一个内置的,但你想要实现的可以很容易地完成:
def null_coalesce(*a):
return next(x for x in a if x)
它很懒,所以它会像a or b or c
一样短路,但不像reduce
。
您还可以通过以下方式使其特定于 null:
def null_coalesce(*a):
return next(x for x in a if x is not None)
Is there a built-in function which I can use which acts like a or b?
没有。引用自 this answer on why:
The
or
andand
operators can't be expressed as functions because of their short-circuiting behavior:False and some_function() True or some_function()
in these cases,
some_function()
is never called.A hypothetical
or_(True, some_function())
, on the other hand, would have to callsome_function()
, because function arguments are always evaluated before the function is called.
Is there a built-in implementation of such a null coalesce function?
不,没有。但是,the Python documentation page for itertools
建议如下:
def first_true(iterable, default=False, pred=None):
"""Returns the first true value in the iterable.
If no true value is found, returns *default*
If *pred* is not None, returns the first item
for which pred(item) is true.
"""
# first_true([a,b,c], x) --> a or b or c or x
# first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
return next(filter(pred, iterable), default)
Marco 说得对,没有内置,itertools 有配方。您还可以 pip install boltons
使用 boltons.iterutils.first()
实用程序,如果您想要短路,这是完美的选择。
from boltons.iterutils import first
c = first([a, b])
还有一些其他相关且方便的 reduction tools in iterutils
,例如 one()
。
我已经做了足够多的上述工作,以至于我最终想要一个更高级别的工具,可以在 Python 数据结构,产生 glom
and its Coalesce
功能。
from glom import glom, Coalesce
target = {'b': 1}
spec = Coalesce('a', 'b')
c = glom(target, spec)
# c = 1
(完全公开,如上所述,我维护 glom
和 boltons
,这是个好消息,因为 you can bug me 如果你发现错误。)