Python中计算lis最小值和最大值的列表理解

2024-03-28 19:35:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码来计算列表的最小值和最大值,以节省内存效率

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)

其中points_in_list是一个(大)数字列表。我想知道是否有一种方法可以用列表来计算最小值和最大值并保存内存。


Tags: 方法内存代码in列表for数字float
2条回答

假设一个点有两个属性,xy,那么您可以使用

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

我非常喜欢发电机和理解,但在这种情况下,它们似乎不是正确的方法,因为:

  1. 要计算列表的minmax
  2. 你的单子很大

如果您只想计算minmax中的一个,则可以对其使用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_maxx_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

哦,惊喜

虽然只循环一次的算法在纸上更有效,但它被minmax的内部优化击败。此外,在每个循环中设置var与仅在必要时设置var之间的差异是巨大的。你永远不会停止学习。

相关问题 更多 >