随机删除' x'列表中的元素

时间:2017-07-03 11:00:46

标签: python list random

我想在不改变列表顺序的情况下随机删除列表中的一小部分元素。

说我有一些数据,我想删除其中的1/4:

data = [1,2,3,4,5,6,7,8,9,10]
n    = len(data) / 4

我认为我需要一个循环来浏览数据并删除一个随机元素' n'次?如下所示:

for i in xrange(n):
    random = np.randint(1,len(data))
    del data[random]

我的问题是,这是最多的' pythonic'这样做的方式?我的列表长度约为5000个元素,我想多次使用不同的' n'。

谢谢!

4 个答案:

答案 0 :(得分:5)

顺序删除是一个坏主意,因为列表中的删除是O(n)。而是做这样的事情:

def delete_rand_items(items,n):
    to_delete = set(random.sample(range(len(items)),n))
    return [x for i,x in enumerate(items) if not i in to_delete]

答案 1 :(得分:4)

您可以像这样使用random.sample

import random

a = [1,2,3,4,5,6,7,8,9,10]

no_elements_to_delete = len(a) // 4
no_elements_to_keep = len(a) - no_elements_to_delete
b = set(random.sample(a, no_elements_to_keep))  # the `if i in b` on the next line would benefit from b being a set for large lists
b = [i for i in a if i in b]  # you need this to restore the order
print(len(a))  # 10
print(b)       # [1, 2, 3, 4, 5, 8, 9, 10]
print(len(b))  # 8

以上两点说明。

  1. 您没有修改原始列表,但可以。
  2. 你实际上并没有删除元素,而是保留元素,但它是一样的(你只需要调整比率)
  3. 缺点是恢复元素顺序的列表理解
  4. 正如@koalo在评论中所说,如果原始列表中的元素不是唯一,则上述将无法正常工作。我可以轻松解决这个问题,但后来我的答案与@ JohnColeman发布的答案相同。因此,如果可能是这种情况,只需使用他的。

答案 2 :(得分:0)

订单有意义吗? 如果没有,你可以做类似的事情:

shuffle(data)
data=data[:len(data)-n]

答案 3 :(得分:0)

我建议使用numpy索引,如

import numpy as np
data = np.array([1,2,3,4,5,6,7,8,9,10])
n = len(data)/4
indices = sorted(np.random.choice(len(data),len(data)-n,replace=False))
result = data[indices]