有没有更有效的方法来编写合并函数?

Is there a more efficient way of writing the coalesce function?

查看了一些代码后,发现了以下函数:

def coalesce(*args, null=None):
    return next((obj for obj in args if obj is not null and obj != null), null)

是否有更有效的方法来进行此操作 运行 或更 Pythonic 的思考问题的方式?

第一个尝试的替代方案如下:

def coalesce(*args):
    return next(filter(None, args), None)

这是尝试过的第二种选择:

def coalesce(*args, null=None):
    return next(itertools.filterfalse(functools.partial(operator.eq, null), args), null)

这是想到的第三个备选方案:

def coalesce(*args):
    return next((obj for obj in args if obj is not None), None)

写了第四个替代方案,希望用 C 编写的代码会更快:

def coalesce(*args):
    return next(itertools.filterfalse(functools.partial(operator.is_, None), args), None)

使用timeit,三个不同函数的计时结果为:

这似乎表明第二个函数更可取,但这并没有回答哪个是最 Pythonic 的问题。

你考虑过

def coalesce4(*args):
    for x in args:
        if x is not None:
            return x

这比您问题中显示的三个函数要快得多:

In [2]: import tmp

In [3]: %timeit tmp.coalesce1(None, None, 1)
782 ns ± 1.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit tmp.coalesce2(None, None, 1)
413 ns ± 8.36 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [5]: %timeit tmp.coalesce3(None, None, 1)
678 ns ± 0.782 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [6]: %timeit tmp.coalesce4(None, None, 1)
280 ns ± 0.218 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

在 Python 3.8 中,您可以选择

def coalesce5(*args):
    if any(rv := x for x in args if x is not None):
         return rv

这实际上与您的第三个选项相同,并且类似函数的 运行 时间表明它的速度大致相同(~680 ns)。