为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

潇湘沐 2023-10-11 16:18:23
在我们需要根据条件搜索最佳元素的函数中(例如 Min Max 函数:搜索最小值或最大值),我看到一些(或许多)人检查保存最佳答案的变量是否为 None并排循环进行条件检查。为了说明这一点,让以下2个源代码: A)使用循环内的测试:is Nonelist_vals = [10,9,8,7,6,5,4,3,2,1]min_val = Nonefor val in list_vals:    if min_val is None or val<min_val:        min_val = valprint("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 = valprint("min = ", min_val)我的问题是:为什么有些人采用第一种形式(A)?这是一些好的做法吗?如果我们使用第一个 from,那就意味着在每次迭代中我们都会检查变量是否为 None,我不知道编译器是否对此进行了优化。为了查看此示例的执行时间是否相似,我计算了方法A和B的时间:nb = 100000000 # 100_000_000list_vals = random.sample(range(nb), nb)时间(A) = 24.00 秒时间(B) = 19.31 秒我用其他长度重复测试,结果是一样的,B方法比A方法分析(相对)快。感谢您的帮助。
查看完整描述

1 回答

?
慕神8447489

TA贡献1780条经验 获得超1个赞

在一般代码中,您可能想要使用任意可迭代对象,而不仅仅是list,在这种情况下,只有第一种形式完全有效(您无法索引非序列)。您可能还需要处理潜在的空输入(A 通过生成 来处理它们None,而 B 引发一个IndexError)。它确实增加了非零成本(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:]),您不必为初始情况发明哨兵值,因为您可以安全地获取第一个元素一次,并且您不会针对其自身测试初始值(因为有状态迭代器仅产生初始值一次)。


查看完整回答
反对 回复 2023-10-11
  • 1 回答
  • 0 关注
  • 76 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信