Min Max 类函数,使用 if best == None 和 Python 循环内的条件

Min Max like function, using if best == None with the condition inside the loop in Python

在我们需要根据条件搜索最佳元素的函数中(例如 Min Max 函数:搜索最小值或最大值),我看到一些(或许多)人检查变量是否保持最佳答案是 None 在循环内与条件检查并排。

为了说明这一点,让以下2个源代码:
A) 在循环中使用测试 is None:

list_vals = [10,9,8,7,6,5,4,3,2,1]

min_val = None

for val in list_vals:
    if min_val is None or val<min_val:
        min_val = val

print("min = ", min_val)

B) 最好接收第一个元素

list_vals = [10,9,8,7,6,5,4,3,2,1]

min_val = list_val[0]

for val in list_vals:
    if val<min_val:
        min_val = val

print("min = ", min_val)

我的问题是:

为了查看此示例的执行时间是否相似,我计算了方法 AB 的时间

nb = 100000000 # 100_000_000
list_vals = random.sample(range(nb), nb)

我用其他长度重复了测试,结果是一样的,B方法比A方法分析(相对)快。

感谢您的帮助。

编辑一:假设 list_vals 不为空。谢谢@0x5453

在通用代码中,您可能希望使用任意可迭代对象,而不仅仅是 list,在这种情况下,只有第一种形式有效(您无法索引 non-sequences)。您可能还需要处理可能为空的输入(A 通过生成 None 来处理它们,而 B 引发 IndexError)。它确实增加了 non-zero 成本(CPython 只有最简单、最局部的优化器;它不能像“min_val 只是第一个循环中的 None”这样的广泛推论)。如果性能至关重要,您可以通过这种方式获得两全其美(尽管代码略显丑陋):

vals = ... could be any iterable ...

iter_vals = iter(vals)  # Explicitly convert to iterator (if already an iterator, just returns vals at trivial cost)

min_val = next(iter_vals, None)  # Pulls first value, or None if vals was empty

for val in iter_vals:  # Iterates rest of values looking for minimum
    if val < min_val:
        min_val = val

print("min = ", min_val)

在这种情况下,您不需要假设输入是一个序列,您不会制作不必要的数据副本(切片 list_vals[1:] 可以做到),您不必发明一个哨兵初始情况的值,因为您可以安全地获取第一个元素一次,并且您不会针对自身测试初始值(因为有状态迭代器只产生一次初始值)。