Mengenai jawaban oleh @Hugh Bothwell, @mortehu dan @glglgl.
Setup Dataset untuk pengujian
import random
dataset = [random.randint(0,15) if random.random() > .6 else None for i in range(1000)]
Tetapkan implementasi
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)
Buat fungsi tes
def test_func(dataset, func):
default = 1
for i in dataset:
func(i, default)
Hasil pada mac i7 @ 2.7Ghz menggunakan python 2.7
>>> %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
Jelas itu not_none
fungsi menjawab pertanyaan OP dengan benar dan menangani masalah "falsy". Ini juga yang tercepat dan termudah untuk dibaca. Jika menerapkan logika di banyak tempat, itu jelas cara terbaik untuk pergi.
Jika Anda memiliki masalah di mana Anda ingin menemukan nilai bukan nol pertama di iterable, maka respons @ mortehu adalah cara yang harus dilakukan. Tetapi ini adalah solusi untuk masalah yang berbeda dari OP, meskipun sebagian dapat menangani kasus itu. Itu tidak bisa mengambil nilai ANDER default. Argumen terakhir adalah nilai default yang dikembalikan, tetapi Anda tidak akan meneruskan iterable dalam kasus itu dan juga tidak eksplisit bahwa argumen terakhir adalah nilai default.
Anda kemudian dapat melakukan di bawah ini, tetapi saya masih akan menggunakan not_null
untuk kasus penggunaan nilai tunggal.
def coalesce(*args, **kwargs):
default = kwargs.get('default')
return next((a for a in arg if a is not None), default)
??
operator diusulkan sebagai PEP 505 .