我试图编写一个python程序,从列表中删除25%的最低值,并返回原始的未排序列表。例如;
Input : [1,5,6,72,3,4,9,11,3,8]
Output : [5,6,72,4,9,11,8]
我试着这样做:
l = [1,5,6,72,3,4,9,11,3,8]
def drop(k):
while len(l)!=0 and k > 0:
k = k - 1
l.sort(reverse = True)
l.pop()
return l
k = math.ceil(len(l) * 0.25)
drop (k)
它返回[72,11,9,8,6,5,4],但有没有办法在没有排序的情况下做到这一点?。
答案 0 :(得分:1)
您可以使用heapq
并保持弹出元素,直到已删除25%的容器。然后,过滤原始列表的内容
import heapq, copy
s = [1,5,6,72,3,4,9,11,3,8]
new_s = copy.deepcopy(s)
heapq.heapify(s)
count = 0
last_items = set()
while count/float(len(new_s)) <= 0.25:
last_items.add(heapq.heappop(s))
count += 1
final_s = [i for i in new_s if i not in last_items]
输出:
[5, 6, 72, 4, 9, 11, 8]
答案 1 :(得分:1)
您不需要反向排序并找到最小的元素。在列表min
上使用l
可返回l
中的最小值,并可方便地使用l.remove
删除。
import math
l = [1,5,6,72,3,4,9,11,3,8]
def drop(k):
while len(l)!=0 and k > 0:
k = k - 1
l.remove(min(l))
return l
k = math.ceil(len(l) * 0.25)
print(drop (k))
# [5, 6, 72, 4, 9, 11, 8]
答案 2 :(得分:1)
这样做的一种方法是这对于更长的列表来说非常慢!:
quart_len = int(0.25*len(l))
for i in range(quart_len):
l.remove(min(l))
更快的方法:
import numpy as np
from math import ceil
l = [1,5,6,72,3,4,9,11,3,8]
sorted_values = np.array(l).argsort()
l_new = [l[i] for i in range(len(l)) if i in sorted_values[int(ceil(len(l)/4.)):]]
另一种方法:
l = np.array(l)
l = list(l[l > sorted(l)[len(l)/4]])
答案 3 :(得分:1)
this problem有O(n)个解决方案。其中之一,introselect,在partition
和argpartition
函数中实现了numpy:
>>> data = [1,5,6,72,3,4,9,11,3,8]
>>>
>>> k = int(round(len(data) / 4))
>>>
>>> import numpy as np
>>> dnp = np.array(data)
>>> drop_them = np.argpartition(dnp, k)[:k]
>>> keep_them = np.ones(dnp.shape, dtype=bool)
>>> keep_them[drop_them] = False
>>> result = dnp[keep_them].tolist()
>>>
>>> result
[5, 6, 72, 4, 9, 11, 3, 8]
请注意,此方法会保留其中一个3
并删除另一个,以便在k
个元素中进行拆分。
如果您希望将所有3
视为相同,则可以执行
>>> boundary = np.argpartition(dnp, k)[k]
>>> result = dnp[dnp > dnp[boundary]]
>>>
>>> result
array([ 5, 6, 72, 4, 9, 11, 8])
答案 4 :(得分:0)
l1=[1,5,6,72,3,4,9,11,3,8]
l2=sorted(l1)
ln=round(len(l1)*0.25)
[i for i in l1 if i not in l2[ln+1:]]
输出:
[5, 6, 72, 4, 9, 11, 8]