Gia*_*ear 7 python list-comprehension list max min
我有以下代码来计算列表的最小值和最大值,以节省内存效率
x_min = float('+inf')
x_max = float('-inf')
for p in points_in_list:
x_min = min(x_min, p)
x_max = max(x_max, p)
Run Code Online (Sandbox Code Playgroud)
其中points_in_list是(大)数字列表.我想知道是否有一种方法可以使用List Comprehensions计算最小值和最大值并保存内存.
我是发电机和理解的忠实粉丝,但在这种情况下,似乎它们不是正确的方法,因为:
min和max列表如果你想只计算的一个min或者max,你可以只使用它的最小值/最大值功能.但既然你想要两者,你必须循环遍历列表两次以提取最小值然后最大值.就是这样的:
x_min = min(points)
x_max = max(points)
Run Code Online (Sandbox Code Playgroud)
让我们玩一些时间.首先在列表中调用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
Run Code Online (Sandbox Code Playgroud)
现在只使用你的代码循环一次:
>>> 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
Run Code Online (Sandbox Code Playgroud)
疯了,是吗?
这种方法完全没有内存问题.但是,它设置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
Run Code Online (Sandbox Code Playgroud)
OH SURPRISE
虽然循环算法只有一次在纸上更有效,但它被内部优化min和max.而且,在每个循环中设置var并且仅在必要时之间的差异是巨大的.你永远不会停止学习.
假设一个点有两个属性,x并且y,然后就可以使用
x_min = min(p['x'] for p in points_in_list) 计算x的最小值
一个例子:
>>> a = {'x': 10, 'y':10}
>>> b = {'x': 5, 'y':20}
>>> c = {'x': 50, 'y':50}
>>> points_in_list = [a,b,c]
>>> points_in_list
[{'y': 10, 'x': 10}, {'y': 20, 'x': 5}, {'y': 50, 'x': 50}]
>>> x_min = min(p['x'] for p in points_in_list)
>>> x_min
5
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7903 次 |
| 最近记录: |