我非常喜欢发电机和理解,但在这种情况下,它们似乎不是正确的方法,因为:要计算列表的min和max
你的单子很大
如果您只想计算min或max中的一个,则可以对其使用min/max函数。但是由于两者都需要,因此必须循环遍历列表两次,先提取最小值,然后提取最大值,例如:x_min = min(points)
x_max = max(points)
我们来玩玩计时吧。首先调用列表中的min和max:>>> import timeit
>>> def with_gens(l):
... return min(l), max(l)
...
>>> timeit.timeit('with_gens(range(6000000))', 'from __main__ import with_gens', number=5)
1.7451060887015188
现在只循环一次,使用您的代码:>>> def with_loop2(l):
... x_max = float('+inf')
... x_min = float('-inf')
... for el in l:
... x_min = min(x_min, el)
... x_max = max(x_max, el)
... return x_min, x_max
...
>>> timeit.timeit('with_loop2(range(6000000))', 'from __main__ import with_loop2', number=5)
11.636076105071083
疯了吧?
这种方法完全没有内存问题。但是,它在每个循环中设置x_max和x_min,这实际上是一种不必要的浪费:您只想在找到更大/更小的值时重置变量。我们可以很容易地解决这个问题。
所以。。。我们只循环一次,但要避免不必要的重置。>>> def with_loop(l):
... x_min = float('-inf')
... x_max = float('+inf')
... for el in l:
... if el < x_min:
... x_min = el
... elif el > x_max:
... x_max = el
... return x_min, x_max
...
>>> timeit.timeit('with_loop(range(6000000))', 'from __main__ import with_loop', number=5)
3.961046726963332
哦,惊喜
虽然只循环一次的算法在纸上更有效,但它被min和max的内部优化击败。此外,在每个循环中设置var与仅在必要时设置var之间的差异是巨大的。你永远不会停止学习。