在 Python 中,我如何随机选择一个列表中不在第二个列表中的元素?

In Python, how can I randomly chose an element of one list that's NOT in a second list?

假设我有 list2 个从大型 list1 中随机选择的元素。有没有一种聪明的方法可以从 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 循环更有效的方法。

如果 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 异常。

您可以从 list1 中减去 list2

list3 = list(set(list1)-set(list2))

并随机选择:

random.choice(list3)

注意: 您需要将 set 重新转换为 list

您可以使用:

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.

中删除重复元素

如果您想从列表中随机 select 多个项目,或从一组中 select 一个项目,最好使用 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)

如果您不希望创建一个新列表(或一个新列表和两个集合)的开销在 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 循环以确保删除所有出现的项目。