如何检查以下项目之一是否在列表中?

我试图find一个简短的方法来查看是否有任何下列项目在列表中,但我的第一次尝试不起作用。 除了写一个函数来完成这个任务之外,还有一个简单的方法来检查多个项目之一是否在列表中。

>>> a = [2,3,4] >>> print (1 or 2) in a False >>> print (2 or 1) in a True 
 >>> L1 = [2,3,4] >>> L2 = [1,2] >>> [i for i in L1 if i in L2] [2] >>> S1 = set(L1) >>> S2 = set(L2) >>> S1.intersection(S2) set([2]) 

空列表和空集都是False,因此您可以直接将该值用作真值。

啊,托比亚斯你把我打倒了。 我正在考虑你的解决scheme上的这个细微的变化:

 print any(x in a for x in b) 

想想代码实际上说的是什么!

 >>> (1 or 2) 1 >>> (2 or 1) 2 

这应该可以解释它。 🙂 Python显然实现了“懒惰或”,这应该不令人意外。 它执行这样的事情:

 def or(x, y): if x: return x if y: return y return False 

在第一个例子中, x == 1y == 2 。 在第二个例子中,反之亦然。 这就是为什么它根据它们的顺序返回不同的值。

也许有点懒:

 a = [1,2,3,4] b = [2,7] print any((True for x in a if x in b)) 
 a = {2,3,4} if {1,2} & a: pass 

代码高尔夫版本。 考虑使用一个集合,如果这样做是有道理的。 我觉得这比列表理解更可读。

1行没有列表parsing。

 >>> any(map(lambda each: each in [2,3,4], [1,2])) True >>> any(map(lambda each: each in [2,3,4], [1,5])) False >>> any(map(lambda each: each in [2,3,4], [2,4])) True 

最好的我可以拿出来:

 any([True for e in (1, 2) if e in a]) 

在某些情况下(如独特的列表元素),可以使用set操作。

 >>> a=[2,3,4] >>> set(a) - set([2,3]) != set(a) True >>> 

或者,使用set.isdisjoint() ,

 >>> not set(a).isdisjoint(set([2,3])) True >>> not set(a).isdisjoint(set([5,6])) False >>> 

当你想“检查一下b”时,想想哈希(在这种情况下,设置)。 最快的方法是散列你想检查的列表,然后检查那里的每个项目。

这就是为什么Joe Koberg的答案是快速的:检查集合交集是非常快的。

当你没有太多的数据时,制作集合可能是浪费时间。 所以,你可以做一个列表,只是检查每个项目:

 tocheck = [1,2] # items to check a = [2,3,4] # the list a = set(a) # convert to set (O(len(a))) print [i for i in tocheck if i in a] # check items (O(len(tocheck))) 

当你想检查的项目数量很小,差异可以忽略不计。 但是要检查大量的数字…

testing:

 from timeit import timeit methods = ['''tocheck = [1,2] # items to check a = [2,3,4] # the list a = set(a) # convert to set (O(n)) [i for i in tocheck if i in a] # check items (O(m))''', '''L1 = [2,3,4] L2 = [1,2] [i for i in L1 if i in L2]''', '''S1 = set([2,3,4]) S2 = set([1,2]) S1.intersection(S2)''', '''a = [1,2] b = [2,3,4] any(x in a for x in b)'''] for method in methods: print timeit(method, number=10000) print methods = ['''tocheck = range(200,300) # items to check a = range(2, 10000) # the list a = set(a) # convert to set (O(n)) [i for i in tocheck if i in a] # check items (O(m))''', '''L1 = range(2, 10000) L2 = range(200,300) [i for i in L1 if i in L2]''', '''S1 = set(range(2, 10000)) S2 = set(range(200,300)) S1.intersection(S2)''', '''a = range(200,300) b = range(2, 10000) any(x in a for x in b)'''] for method in methods: print timeit(method, number=1000) 

速度:

 M1: 0.0170331001282 # make one set M2: 0.0164539813995 # list comprehension M3: 0.0286040306091 # set intersection M4: 0.0305438041687 # any M1: 0.49850320816 # make one set M2: 25.2735087872 # list comprehension M3: 0.466138124466 # set intersection M4: 0.668627977371 # any 

一贯快速的方法是创build一个(列表),但交叉点在大型数据集上工作最好!

这将在一行中完成。

 >>> a=[2,3,4] >>> b=[1,2] >>> bool(sum(map(lambda x: x in b, a))) True 
 print (1 in a) or (2 in a) print (2 in a) or (5 in a) 

这是一个非常古老的问题,但我对任何答案都不满意,所以为了后人的缘故,我不得不加上这个。

简单。

 _new_list = [] for item in a: if item in b: _new_list.append(item) else: pass