从列表中随机删除“ x”个元素

Ric*_*all 4 python random list

我想从列表中随机删除一部分元素,而无需更改列表的顺序。

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

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

我在想我需要一个循环来遍历数据并删除一个随机元素'n'次?所以像这样:

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

我的问题是,这是最“ Pythonic”的方式吗?我的列表将有大约5000个元素,我想使用不同的'n'值进行多次。

谢谢!

Joh*_*man 6

顺序删除是个坏主意,因为列表中的删除为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]
Run Code Online (Sandbox Code Playgroud)


Ev.*_*nis 5

您可以像这样使用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
Run Code Online (Sandbox Code Playgroud)

上面有两个注释。

  1. 您没有就地修改原始列表,但您可以。
  2. 您实际上并不是删除元素,而是保留元素,但这是同一件事(您只需调整比率)
  3. 缺点是列表理解会恢复元素的顺序

正如 @koalo 在评论中所说,如果原始列表中的元素不唯一,则上述内容将无法正常工作。我可以轻松解决这个问题,但我的答案将与@JohnColeman 发布的答案相同。所以如果是这种情况,就用他的吧。