从同一行代码的列表中删除最小和最大数量
Removing min and max number from list on the same line of code
列表:
RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4]
目前我正在使用以下方法从列表中删除最高和最低的数字:
RawScores.remove(max(RawScores))
RawScores.remove(min(RawScores))
我想知道是否有另一种或更有效的方法可以产生相同的结果,但只需一行代码即可实现。
当然可以:
without_min_max = [item for item in RawScores if item != max(RawScores) and item != min(RawScores)]
您可能希望对列表进行排序和切片,以便删除第一个和最后一个元素,除非您负担不起对列表进行排序的费用:
RawScores = sorted(RawScores)[1:-1]
这是一个衬垫:
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
在一行中?是的。高效的?编号
>>> 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)。
您可以尝试使用过滤器:
nominmax = filter(lambda value: (value != max(RawScores) and value !=
min(RawScores)), RawScores)
这可能看起来微不足道,但您可以将两个语句放在同一行:
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)
显然,只计算一次最小值和最大值而不是对每个元素计算一次是有意义的。不过,就地删除是最快的。
列表:
RawScores = [3.4,1.2,5.8,7.2,2.8,9.1,7.6,4]
目前我正在使用以下方法从列表中删除最高和最低的数字:
RawScores.remove(max(RawScores))
RawScores.remove(min(RawScores))
我想知道是否有另一种或更有效的方法可以产生相同的结果,但只需一行代码即可实现。
当然可以:
without_min_max = [item for item in RawScores if item != max(RawScores) and item != min(RawScores)]
您可能希望对列表进行排序和切片,以便删除第一个和最后一个元素,除非您负担不起对列表进行排序的费用:
RawScores = sorted(RawScores)[1:-1]
这是一个衬垫:
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
在一行中?是的。高效的?编号
>>> 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)。
您可以尝试使用过滤器:
nominmax = filter(lambda value: (value != max(RawScores) and value !=
min(RawScores)), RawScores)
这可能看起来微不足道,但您可以将两个语句放在同一行:
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)
显然,只计算一次最小值和最大值而不是对每个元素计算一次是有意义的。不过,就地删除是最快的。