Min Max 类似函数,使用 if best == None 和 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)

我的问题是:


为什么有些人采用第一种形式(A)?这是一些好的做法吗?

如果我们使用第一个 from,那就意味着在每次迭代中我们都会检查变量是否为 None,我不知道编译器是否对此进行了优化。

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


nb = 100000000 # 100_000_000

list_vals = random.sample(range(nb), nb)

时间(A) = 24.00 秒

时间(B) = 19.31 秒

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


感谢您的帮助。


潇湘沐
浏览 53回答 1
1回答

慕神8447489

在一般代码中,您可能想要使用任意可迭代对象,而不仅仅是list,在这种情况下,只有第一种形式完全有效(您无法索引非序列)。您可能还需要处理潜在的空输入(A 通过生成 来处理它们None,而 B 引发一个IndexError)。它确实增加了非零成本(CPython 只有最简单、最本地化的优化器;它不能做出像“min_val仅None在第一个循环上”这样的广泛推论)。如果性能至关重要,您可以通过以下方式获得两全其美(尽管代码稍显丑陋):vals = ... could be any iterable ...iter_vals = iter(vals)&nbsp; # Explicitly convert to iterator (if already an iterator, just returns vals at trivial cost)min_val = next(iter_vals, None)&nbsp; # Pulls first value, or None if vals was emptyfor val in iter_vals:&nbsp; # Iterates rest of values looking for minimum&nbsp; &nbsp; if val < min_val:&nbsp; &nbsp; &nbsp; &nbsp; min_val = valprint("min = ", min_val)在这种情况下,您不会假设输入是序列,您不会制作不必要的数据副本(切片会这样做list_vals[1:]),您不必为初始情况发明哨兵值,因为您可以安全地获取第一个元素一次,并且您不会针对其自身测试初始值(因为有状态迭代器仅产生初始值一次)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python