在第一个列表中随机选择一个不属于第二个列表的元素。

3

假设我有一个从大型list1中随机选择的元素列表list2。是否有一种聪明的方法来选择list1中尚未包含在list2中的元素?

例如:

list1 = range(20,100)
list2 = [37,49,22,35,72] # could be much longer
    
while True:
    n = random.choice(list1)
    if n not in list2:
        break
    
# now n is an element of list1 that's not in list2

我觉得肯定有比猜测和检查 while 循环更高效的方法。

5个回答

3
您可以从list1中减去list2:
list3 = list(set(list1)-set(list2))

并随机从中选择:

random.choice(list3)

注意: 您需要将set转换回list


2

您可以使用以下方法:

import random

list1 = range(20,100)
list2 = [37,49,22,35,72]

not_in_list2 = [item for item in list1 if item not in list2]
n = random.choice(not_in_list2)

使用列表推导式创建一个列表,其中包含在list1中但不在list2中的所有元素。然后从此列表中随机选择。与使用集合时不同,此技术不会更改选择元素的概率,因为它不会从list1中删除重复元素。


1
如果列表list1中没有重复元素,这是一种Pythonic的方式,使用set和-操作符:
import random

list1 = range(20,100)
list2 = [37,49,22,35,72] # could be much longer

n = random.choice(tuple(set(list1)-set(list2)))

# now n is an element of list1 that's not in list2

需要调用tuple来避免出现NotIndexable异常。


0

如果您不想创建一个新列表(或新列表和两个集合)的开销,因为list1非常大而变得非常昂贵,那么还有另一种选择。

import random

list1 = range(20,100)
list2 = [37,49,22,35,72]

for i in list2:
    while i in list1:
        list1.remove(i)

random.choice(list1)

只需迭代 list2 中的项目并从 list1 中删除它们。由于 list.remove() 只删除项目的第一个出现,因此我添加了一个 while 循环以确保所有出现都被删除。


0
如果你想从一个列表中随机选择多个项目,或者从一个集合中选择一个项目,最好使用random.sample而不是choice
import random
diff = set(list1)-set(list2)
num_to_select = 1 # set the number to select here.
list_of_random_items = random.sample(diff, num_to_select)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接