@Hugh Bothwell、@ mortehu、@ glglglの回答について。
テスト用のセットアップデータセット
import random
dataset = [random.randint(0,15) if random.random() > .6 else None for i in range(1000)]
実装を定義する
def not_none(x, y=None):
if x is None:
return y
return x
def coalesce1(*arg):
return reduce(lambda x, y: x if x is not None else y, arg)
def coalesce2(*args):
return next((i for i in args if i is not None), None)
テスト機能を作る
def test_func(dataset, func):
default = 1
for i in dataset:
func(i, default)
Python 2.7を使用したMac i7 @ 2.7Ghzでの結果
>>> %timeit test_func(dataset, not_none)
1000 loops, best of 3: 224 µs per loop
>>> %timeit test_func(dataset, coalesce1)
1000 loops, best of 3: 471 µs per loop
>>> %timeit test_func(dataset, coalesce2)
1000 loops, best of 3: 782 µs per loop
明らかに、not_none
関数はOPの質問に正しく回答し、「誤りのある」問題を処理します。また、これは最も速く、最も読みやすいものです。ロジックを多くの場所に適用する場合、それが明らかに最良の方法です。
イテラブルで最初のnull以外の値を検索する必要がある場合は、@ mortehuの応答で解決できます。しかし、それはOP とは異なる問題の解決策ですが、そのケースを部分的に処理できます。反復可能かつデフォルト値を取ることはできません。最後の引数は返されるデフォルト値になりますが、その場合は反復可能オブジェクトを渡さないため、最後の引数がデフォルトの値であることは明示されていません。
その後、以下を実行できますが、私はまだnot_null
単一値のユースケースに使用します。
def coalesce(*args, **kwargs):
default = kwargs.get('default')
return next((a for a in arg if a is not None), default)
??
オペレータは次のように提案されているPEP 505。