单次迭代中的最小值、最大值和平均值

2 投票
2 回答
2426 浏览
提问于 2025-04-17 20:47

如果我有一个数字列表,比如 l = [3,5,3,6,47,89]。我们可以用下面的 Python 代码来计算这个列表的最小值、最大值和平均值。

minimum = min(l)
maximum = max(l)
avg = sum(l) / len(l)

因为这些计算都需要遍历整个列表,所以对于很大的列表来说,这样做会比较慢,而且代码也会很多。有没有什么 Python 模块可以一次性计算这些值呢?

2 个回答

3

如果你安装了pandas库,你可以这样做:

import numpy as np
import pandas
s = pandas.Series(np.random.normal(size=37))
stats = s.describe()

stats会变成另一个像字典一样的序列:

print(stats)
count    37.000000
mean      0.072138
std       0.932000
min      -1.267888
25%      -0.688728
50%      -0.048624
75%       0.784244
max       2.501713
dtype: float64

stats['max']
2.501713

……等等。不过,我不太推荐这样做,除非你只是想让代码更简洁。原因如下:

%%timeit
stats = s.describe()
# 100 loops, best of 3: 1.44 ms per loop

%%timeit
mymin = min(s)
mymax = max(s)
myavg = sum(s)/len(s)
# 10000 loops, best of 3: 89.5 µs per loop

我实在想象不出你能通过自己的实现让内置函数的性能更好(除非你用一些特别的技巧,比如cython)。

3

Cython 函数:

@cython.boundscheck(False)
@cython.wraparound(False)
def minmaxAvg(list x):

    cdef int i
    cdef int _min, _max, total
    _min = x[0]
    _max = x[0]
    total = 0
    for i in x:
        if i < _min: _min = i 
        elif i > _max: _max = i 
        total += i
    return _min, _max, total/len(x)

用纯 Python 写的函数,用来做对比:

def builtinfuncs(x):
    a = min(x)
    b = max(x)
    avg = sum(x) / len(x)
    return a,b,avg


In [16]: x = [random.randint(0,1000) for _ in range(10000)]

In [17]: %timeit minmaxAvg(x)
10000 loops, best of 3: 34 µs per loop

In [18]: %timeit frob(x)
1000 loops, best of 3: 460 µs per loop

免责声明:
- Cython 的速度表现会受到电脑硬件的影响。
- 不像内置函数那样灵活和可靠。例如,如果要处理非整数,你需要修改函数。
- 在选择这种方式之前,问问自己这个操作在你的应用中是否真的成了瓶颈。大多数情况下,它可能并不是。

撰写回答