最具python风格的方法是在带有条件的列表中随机选择一个元素
我有两份清单:最具python风格的方法是在带有条件的列表中随机选择一个元素,python,python-3.x,random,conditional-statements,Python,Python 3.x,Random,Conditional Statements,我有两份清单: list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2 = [1, 4, 5] 我想从list1中选择一个元素,但它不应该属于list2 我有一个使用while循环的解决方案,但我希望有一个更具python风格和优雅的单行程序 [item for item in list1 if not in list2] 要使其更快一点(因为在集合中查找比在列表中查找快): 或者使用filter函数(您将在Python3中获得一个生成器对象) filte
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = [1, 4, 5]
我想从list1
中选择一个元素,但它不应该属于list2
我有一个使用while循环的解决方案,但我希望有一个更具python风格和优雅的单行程序
[item for item in list1 if not in list2]
要使其更快一点(因为在集合中查找比在列表中查找快):
或者使用filter函数(您将在Python3中获得一个生成器对象)
filter(lambda item: item not in list2, list1)
将list2转换为set也将加快此处的过滤速度
要获得更多信息,请阅读
更新:关于一个随机值,我似乎遗漏了一点。好吧,您仍然可以使用列表理解,但使用random.choice
,如前所述:
import random
random.choice([item for item in list1 if not in list2_items])
它将筛选选择,然后随机获得一个。@zeehio响应看起来是更好的解决方案
import random
import itertools
next(item for item in (random.choice(list1) for _ in itertools.count()) if item not in list2)
这相当于:
while True:
item = random.choice(list1)
if item not in list2:
break
如果元素是唯一的,可以使用集合差异。(将列表1转换为集合,并从列表2中删除元素)。然后随机抽取一个样本
random.choice(list(set(list1).difference(list2)))
您可能希望利用
设置s,如下所示:
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = [1, 4, 5]
import random
print(random.choice([x for x in set(list1).difference(list2)])) # kudos @chepner
这样,我们就可以从set(list1)-set(list2)
中随机抽取list1
中的元素,而不是list2
中的元素。这种方法还可以在列表1和列表2变大时进行扩展
@MSeifert注意到,将list1
转换为set
将删除list1
中可能存在的任何重复元素,从而改变概率。如果list1
在一般情况下可能包含重复元素,则您可能希望这样做:
print(random.choice([x for x in list1 if x not in list2]))
不导入随机库:
print((list(set(list1) - set(list2))).pop())
在pop()中,您可以给出要选择的元素的索引,它将弹出该元素
示例:用于选择索引1的列表(从新列表),((列表(设置(列表1)-set(列表2))).pop(1))
这里的(list(set(list1)-set(list2))
代码将创建一个新列表,其中只包含第一个列表中的项目,而这些项目在第二个列表中不存在,尝试以下操作:使用set(list1).差异(list2)
,您不需要构造第二个显式集合。difference
将任何iterable作为参数,而不仅仅是集合。@chepner那么您可能是指set(list1)。difference(list2)
,对吧?set2
,list2
,随便:)谢谢。还需要注意的是,这将丢弃列表1
中的任何重复项(不仅仅是列表2
中的重复项)因此会扭曲概率。没有错,但可能需要无限次迭代的东西感觉不对劲。@chepner没错,但是set
方法可能是错误的,因为它们需要散列值并丢弃重复项(因此可能会扭曲概率)。也许检查一些元素是否仍保留在列表1
中会很好,但否则很难有一个“一个来统治所有元素”的方法。在这种情况下,它很少需要超过2次尝试,它是O(1)
,而集-方法是O(n)
具有相当高的常数因子。如果选择出现在列表2
中的元素的概率很高,则在调用random.choice
之前过滤list1
可能是值得的。这是正确的。对于包含哈希值set
的长iterables,显然是更好的选择。注意当什么都不符合标准时,无限循环这并不能解决随机选择。是的,谢谢你指出。我错过了问题标签,误解了它。
print((list(set(list1) - set(list2))).pop())