随机删除列表中的项目百分比

时间:2017-10-12 20:25:15

标签: python python-3.x

我有一个n个元素的列表。现在我必须删除此列表中所有元素的百分比。删除的元素必须全部随机选取。

例如,设n = 0,2(要删除20%)

n = 0.2
list = [one, two, three, four, five, six, seven, eight, nine, ten]

随机删除20%后,列表将是:

list = [one, three, four, five, seven, eight, nine, ten] # two and seven deleted

现在你可能会想,嗯,这不是那么难......嗯,这一切都必须在一条线上完成,我对那些oneliners来说是新手......

因此必须创建一个新函数,该函数返回相同的列表但没有元素的百分比:

def remove(n, list):
    return list # But the new list with elements removed

请帮助,返回后面输入什么内容?

3 个答案:

答案 0 :(得分:6)

您可以使用random.sample来挑选(100*(1-n))%项:

import random

def remove(l,n):
    return random.sample(l,int(len(l)*(1-n)))

print(remove(list(range(1,11)),0.2))

结果:

[10, 8, 4, 7, 1, 9, 6, 2]

请注意浮动到整数舍入,你可以抛出一个int(len(l)*(1-n)+0.5)来避免截断并改为最接近。

编辑:另一种方法是pop计算随机索引中的项目数(每次更简单重新计算列表的len,以避免索引超出范围):

def remove(l,n):
    for _ in range(int(len(l)*n)):
        l.pop(random.randrange(0,len(l)))
    return l

不是列表理解,不是单行,而是就地工作。当要删除的项目百分比较低时,可能会更快。

答案 1 :(得分:0)

你可以试试这个:

import random
list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
new_list = [b for b in list if b not in [random.choice(list) for i in range(int(len(list)*0.2))]]

输出:

['one', 'three', 'four', 'six', 'seven', 'eight', 'nine', 'ten']

答案 2 :(得分:0)

取决于“一行”是否必须在return之后,此列表理解使用lst.pop(i)来删除一行中随机生成的一小部分i中的项目,将索引反向排序,最后弹出以避免可能的索引超出范围错误

lst = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]

def remove(n, lst):
    [lst.pop(i) for i in sorted(random.sample(range(len(lst)), k=int(len(lst)*n)),
                                reverse=True)]
    return lst 

remove(0.2, lst)
Out[37]: ['one', 'two', 'three', 'four', 'seven', 'eight', 'nine', 'ten']

我们修改了lst本身:

lst
Out[38]: ['one', 'two', 'three', 'four', 'seven', 'eight', 'nine', 'ten']

刷新lst

lst = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]

并提供remove() lst

的副本
remove(0.2, lst[:])
Out[40]: ['one', 'two', 'three', 'four', 'six', 'eight', 'nine', 'ten']

并且原始列表是预先设定的:

lst
Out[41]: ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']

如果问题确实存在,实际上只指定了一行代码,与return内联,那么你可以滥用内联if-else:

def remove(n, lst):
    return lst if [lst.pop(i) 
                   for i in sorted(random.sample(range(len(lst)),
                                                 k=int(len(lst)*n)),
                                   reverse=True)] else lst