浏览一些代码后,发现以下功能:
def coalesce(*args, null=None):
return next((obj for obj in args if obj is not null and obj != null), null)
是否有更有效的方法来运行此操作,或者以更Python化的方式思考问题?
第一个尝试的替代方法如下:
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的问题。
答案 0 :(得分:2)
您考虑过
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)。