เกี่ยวกับคำตอบของ @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)
ผลลัพธ์บน mac i7 @ 2.7Ghz ใช้ 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
เห็นได้ชัดว่าnot_none
ฟังก์ชั่นตอบคำถามของ OP ได้อย่างถูกต้องและจัดการปัญหา "ผิดพลาด" นอกจากนี้ยังเป็นวิธีที่เร็วและง่ายที่สุดในการอ่าน หากใช้ตรรกะในหลาย ๆ ที่มันเป็นวิธีที่ดีที่สุดที่จะไปอย่างชัดเจน
หากคุณมีปัญหาที่คุณต้องการค้นหาค่าที่ไม่เป็นค่าที่ 1 ใน iterable การตอบสนองของ @ mortehu คือหนทางที่จะไป แต่มันเป็นวิธีการแก้ไขปัญหาที่แตกต่างจาก OP แม้ว่ามันจะสามารถจัดการกับกรณีนั้นได้บางส่วน มันไม่สามารถใช้ iterable และเป็นค่าเริ่มต้น อาร์กิวเมนต์สุดท้ายจะเป็นค่าเริ่มต้นที่ส่งคืน แต่จากนั้นคุณจะไม่ผ่านการทำซ้ำในกรณีนั้นรวมทั้งไม่ชัดเจนว่าอาร์กิวเมนต์สุดท้ายนั้นเป็นค่าเริ่มต้นสำหรับค่า
จากนั้นคุณสามารถทำด้านล่าง แต่ฉันยังคงใช้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