从同一行代码中的列表中删除最小和最大数字

时间:2017-05-18 14:35:51

标签: python python-2.7 max min

列表:

RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4]

目前我正在使用以下方法从列表中删除最高和最低数字:

RawScores.remove(max(RawScores))
RawScores.remove(min(RawScores))

我想知道是否有替代或更有效的方法产生相同的结果,但只能在一行代码上实现。

6 个答案:

答案 0 :(得分:5)

这看起来似乎微不足道,但你可以将两个陈述放在同一行:

RawScores.remove(max(RawScores)); RawScores.remove(min(RawScores))

您可以在不必先复制列表的情况下修改列表。

就性能而言,这就是迄今为止提出的方法的比较(在较长的列表上,以使差异更明显):

def a():
    RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4] * 100
    RawScores.remove(max(RawScores)), RawScores.remove(min(RawScores))

def b():
    RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4] * 100
    RawScores = [x for x in RawScores if x != max(RawScores) and x != min(RawScores)]

def c():
    RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4] * 100
    RawScores = sorted(RawScores)[1:-1]

%timeit a()  # 10000 loops, best of 3: 66.3 µs per loop
%timeit b()  # 10 loops, best of 3: 49.3 ms per loop
%timeit c()  # 1000 loops, best of 3: 212 µs per loop

到目前为止,最初的解决方案是最快的。

请不要太认真地对待我的回答。像这样在一行上放置多个语句是可怕的练习。 Python代码应该很漂亮而不是内联:)

更新:我在另一台计算机上运行此程序,其中包括filter解决方案的两个变体:

def d():
    RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4] * 100
    RawScores = list(filter(lambda value: (value != max(RawScores) and value != min(RawScores)), RawScores))

def e():
    RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4] * 100
    RawScores = list(filter(lambda value, ma=max(RawScores), mi=min(RawScores): (value != ma and value != mi), RawScores))


%timeit a()  # 115 µs ± 3.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit b()  # 80 ms ± 1.49 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit c()  # 377 µs ± 777 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit d()  # 78.7 ms ± 94.8 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit e()  # 458 µs ± 22.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

显然,只计算一次min和max而不是每个元素都是有意义的。仍然,就地删除是最快的。

答案 1 :(得分:2)

您可能希望对列表进行排序和切片,以便删除第一个和最后一个元素,除非您无法对列表进行排序:

RawScores = sorted(RawScores)[1:-1]

答案 2 :(得分:2)

在一行?是。高效?否。

>>> RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4]
>>> [x for x in RawScores if x != max(RawScores) and x != min(RawScores)]
[3.4, 5.8, 7.2, 2.8, 7.6, 4]

这项工作正常,但max及其O(n)复杂度被称为len(RawScores)次(同样适用于min),这使得此解决方案无效。

您当前的解决方案完全正常,并以O(n)运行。

答案 3 :(得分:2)

您可以尝试使用过滤器:

nominmax = filter(lambda value: (value != max(RawScores) and value != 
min(RawScores)), RawScores)

答案 4 :(得分:1)

不确定

without_min_max = [item for item in RawScores if item != max(RawScores) and item != min(RawScores)]

答案 5 :(得分:0)

这是一个班轮:

print(*sorted([3.4,1.2,5.8,7.2,2.8,9.1,7.6,4])[1:-1])

输出:

2.8 3.4 4 5.8 7.2 7.6